// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/blink/renderer/core/css/css_math_function_value.h"

#include "third_party/blink/renderer/core/css/css_math_expression_node.h"
#include "third_party/blink/renderer/core/css/css_value_clamping_utils.h"
#include "third_party/blink/renderer/platform/geometry/calculation_expression_node.h"
#include "third_party/blink/renderer/platform/geometry/length.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/size_assertions.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"

namespace blink {

struct SameSizeAsCSSMathFunctionValue : CSSPrimitiveValue {
  Member<void*> expression;
};
ASSERT_SIZE(CSSMathFunctionValue, SameSizeAsCSSMathFunctionValue);

void CSSMathFunctionValue::TraceAfterDispatch(blink::Visitor* visitor) const {
  visitor->Trace(expression_);
  CSSPrimitiveValue::TraceAfterDispatch(visitor);
}

CSSMathFunctionValue::CSSMathFunctionValue(
    const CSSMathExpressionNode* expression,
    ValueRange range)
    : CSSPrimitiveValue(kMathFunctionClass), expression_(expression) {
  is_non_negative_math_function_ = range == kValueRangeNonNegative;
}

// static
CSSMathFunctionValue* CSSMathFunctionValue::Create(
    const CSSMathExpressionNode* expression,
    ValueRange range) {
  if (!expression)
    return nullptr;
  return MakeGarbageCollected<CSSMathFunctionValue>(expression, range);
}

// static
CSSMathFunctionValue* CSSMathFunctionValue::Create(const Length& length,
                                                   float zoom) {
  DCHECK(length.IsCalculated());
  auto calc = length.GetCalculationValue().Zoom(1.0 / zoom);
  return Create(CSSMathExpressionNode::Create(*calc), calc->GetValueRange());
}

bool CSSMathFunctionValue::MayHaveRelativeUnit() const {
  UnitType resolved_type = expression_->ResolvedUnitType();
  return IsRelativeUnit(resolved_type) || resolved_type == UnitType::kUnknown;
}

double CSSMathFunctionValue::DoubleValue() const {
#if DCHECK_IS_ON()
  if (IsPercentage()) {
    DCHECK(!AllowsNegativePercentageReference() ||
           !expression_->InvolvesPercentageComparisons());
  }
#endif
  return ClampToPermittedRange(expression_->DoubleValue());
}

double CSSMathFunctionValue::ComputeSeconds() const {
  DCHECK_EQ(kCalcTime, expression_->Category());
  // TODO(crbug.com/984372): We currently use 'ms' as the canonical unit of
  // <time>. Switch to 's' to follow the spec.
  return ClampToPermittedRange(*expression_->ComputeValueInCanonicalUnit() /
                               1000);
}

double CSSMathFunctionValue::ComputeDegrees() const {
  DCHECK_EQ(kCalcAngle, expression_->Category());
  return ClampToPermittedRange(*expression_->ComputeValueInCanonicalUnit());
}

double CSSMathFunctionValue::ComputeLengthPx(
    const CSSToLengthConversionData& conversion_data) const {
  // |CSSToLengthConversionData| only resolves relative length units, but not
  // percentages.
  DCHECK_EQ(kCalcLength, expression_->Category());
  return ClampToPermittedRange(expression_->ComputeLengthPx(conversion_data));
}

bool CSSMathFunctionValue::AccumulateLengthArray(CSSLengthArray& length_array,
                                                 double multiplier) const {
  return expression_->AccumulateLengthArray(length_array, multiplier);
}

Length CSSMathFunctionValue::ConvertToLength(
    const CSSToLengthConversionData& conversion_data) const {
  if (IsLength())
    return Length::Fixed(ComputeLengthPx(conversion_data));
  return Length(ToCalcValue(conversion_data));
}

static String BuildCSSText(const String& expression) {
  StringBuilder result;
  result.Append("calc");
  result.Append('(');
  result.Append(expression);
  result.Append(')');
  return result.ToString();
}

String CSSMathFunctionValue::CustomCSSText() const {
  const String& expression_text = expression_->CustomCSSText();
  if (expression_->IsMathFunction()) {
    // If |expression_| is already a math function (e.g., min/max), we don't
    // need to wrap it in |calc()|.
    return expression_text;
  }
  return BuildCSSText(expression_text);
}

bool CSSMathFunctionValue::Equals(const CSSMathFunctionValue& other) const {
  return DataEquivalent(expression_, other.expression_);
}

double CSSMathFunctionValue::ClampToPermittedRange(double value) const {
  return IsNonNegative() && value < 0 ? 0 : value;
}

bool CSSMathFunctionValue::IsZero() const {
  if (expression_->ResolvedUnitType() == UnitType::kUnknown)
    return false;
  return expression_->IsZero();
}

bool CSSMathFunctionValue::IsPx() const {
  // TODO(crbug.com/979895): This is the result of refactoring, which might be
  // an existing bug. Fix it if necessary.
  return Category() == kCalcLength;
}

bool CSSMathFunctionValue::IsComputationallyIndependent() const {
  return expression_->IsComputationallyIndependent();
}

scoped_refptr<CalculationValue> CSSMathFunctionValue::ToCalcValue(
    const CSSToLengthConversionData& conversion_data) const {
  return expression_->ToCalcValue(conversion_data, PermittedValueRange(),
                                  AllowsNegativePercentageReference());
}

}  // namespace blink
