/*
 * Copyright (C) 2012-2013 Intel Corporation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above
 *    copyright notice, this list of conditions and the following
 *    disclaimer.
 * 2. Redistributions in binary form must reproduce the above
 *    copyright notice, this list of conditions and the following
 *    disclaimer in the documentation and/or other materials
 *    provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include "third_party/blink/renderer/core/css/resolver/viewport_style_resolver.h"

#include "third_party/blink/renderer/core/css/css_default_style_sheets.h"
#include "third_party/blink/renderer/core/css/css_primitive_value_mappings.h"
#include "third_party/blink/renderer/core/css/css_property_value_set.h"
#include "third_party/blink/renderer/core/css/css_style_sheet.h"
#include "third_party/blink/renderer/core/css/css_to_length_conversion_data.h"
#include "third_party/blink/renderer/core/css/document_style_sheet_collection.h"
#include "third_party/blink/renderer/core/css/media_values_initial_viewport.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
#include "third_party/blink/renderer/core/css/style_rule.h"
#include "third_party/blink/renderer/core/css/style_rule_import.h"
#include "third_party/blink/renderer/core/css/style_sheet_contents.h"
#include "third_party/blink/renderer/core/css_value_keywords.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/frame/viewport_data.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/page/viewport_description.h"

namespace blink {

namespace {

bool HasViewportFitProperty(const CSSPropertyValueSet* property_set) {
  DCHECK(property_set);
  return RuntimeEnabledFeatures::DisplayCutoutAPIEnabled() &&
         property_set->HasProperty(CSSPropertyViewportFit);
}

}  // namespace

ViewportStyleResolver::ViewportStyleResolver(Document& document)
    : document_(document) {
  DCHECK(document.GetFrame());
  initial_viewport_medium_ = MakeGarbageCollected<MediaQueryEvaluator>(
      MediaValuesInitialViewport::Create(*document.GetFrame()));
}

void ViewportStyleResolver::Reset() {
  viewport_dependent_media_query_results_.clear();
  device_dependent_media_query_results_.clear();
  property_set_ = nullptr;
  has_author_style_ = false;
  has_viewport_units_ = false;
  DCHECK(initial_style_);
  initial_style_->SetHasViewportUnits(false);
  needs_update_ = kNoUpdate;
}

void ViewportStyleResolver::CollectViewportRulesFromUASheets() {
  CSSDefaultStyleSheets& default_style_sheets =
      CSSDefaultStyleSheets::Instance();
  WebViewportStyle viewport_style =
      document_->GetSettings() ? document_->GetSettings()->GetViewportStyle()
                               : WebViewportStyle::kDefault;
  StyleSheetContents* viewport_contents = nullptr;
  switch (viewport_style) {
    case WebViewportStyle::kDefault:
      break;
    case WebViewportStyle::kMobile:
      viewport_contents = default_style_sheets.EnsureMobileViewportStyleSheet();
      break;
    case WebViewportStyle::kTelevision:
      viewport_contents =
          default_style_sheets.EnsureTelevisionViewportStyleSheet();
      break;
  }
  if (viewport_contents)
    CollectViewportChildRules(viewport_contents->ChildRules(),
                              kUserAgentOrigin);

  if (document_->IsMobileDocument()) {
    CollectViewportChildRules(
        default_style_sheets.EnsureXHTMLMobileProfileStyleSheet()->ChildRules(),
        kUserAgentOrigin);
  }
  DCHECK(!default_style_sheets.DefaultStyleSheet()->HasViewportRule());
}

void ViewportStyleResolver::CollectViewportChildRules(
    const HeapVector<Member<StyleRuleBase>>& rules,
    Origin origin) {
  for (auto& rule : rules) {
    if (rule->IsViewportRule()) {
      AddViewportRule(*ToStyleRuleViewport(rule), origin);
    } else if (rule->IsMediaRule()) {
      StyleRuleMedia* media_rule = ToStyleRuleMedia(rule);
      if (!media_rule->MediaQueries() ||
          initial_viewport_medium_->Eval(
              *media_rule->MediaQueries(),
              &viewport_dependent_media_query_results_,
              &device_dependent_media_query_results_))
        CollectViewportChildRules(media_rule->ChildRules(), origin);
    } else if (rule->IsSupportsRule()) {
      StyleRuleSupports* supports_rule = ToStyleRuleSupports(rule);
      if (supports_rule->ConditionIsSupported())
        CollectViewportChildRules(supports_rule->ChildRules(), origin);
    }
  }
}

void ViewportStyleResolver::CollectViewportRulesFromImports(
    StyleSheetContents& contents) {
  for (const auto& import_rule : contents.ImportRules()) {
    if (!import_rule->GetStyleSheet())
      continue;
    if (!import_rule->GetStyleSheet()->HasViewportRule())
      continue;
    if (import_rule->MediaQueries() &&
        initial_viewport_medium_->Eval(*import_rule->MediaQueries(),
                                       &viewport_dependent_media_query_results_,
                                       &device_dependent_media_query_results_))
      CollectViewportRulesFromAuthorSheetContents(
          *import_rule->GetStyleSheet());
  }
}

void ViewportStyleResolver::CollectViewportRulesFromAuthorSheetContents(
    StyleSheetContents& contents) {
  CollectViewportRulesFromImports(contents);
  if (contents.HasViewportRule())
    CollectViewportChildRules(contents.ChildRules(), kAuthorOrigin);
}

void ViewportStyleResolver::CollectViewportRulesFromAuthorSheet(
    const CSSStyleSheet& sheet) {
  DCHECK(sheet.Contents());
  StyleSheetContents& contents = *sheet.Contents();
  if (!contents.HasViewportRule() && contents.ImportRules().IsEmpty())
    return;
  if (sheet.MediaQueries() &&
      !initial_viewport_medium_->Eval(*sheet.MediaQueries(),
                                      &viewport_dependent_media_query_results_,
                                      &device_dependent_media_query_results_))
    return;
  CollectViewportRulesFromAuthorSheetContents(contents);
}

void ViewportStyleResolver::AddViewportRule(StyleRuleViewport& viewport_rule,
                                            Origin origin) {
  CSSPropertyValueSet& property_set = viewport_rule.MutableProperties();

  unsigned property_count = property_set.PropertyCount();
  if (!property_count)
    return;

  if (origin == kAuthorOrigin)
    has_author_style_ = true;

  if (!property_set_) {
    property_set_ = property_set.MutableCopy();
    return;
  }

  // We cannot use mergeAndOverrideOnConflict() here because it doesn't
  // respect the !important declaration (but addRespectingCascade() does).
  for (unsigned i = 0; i < property_count; ++i) {
    CSSPropertyValueSet::PropertyReference property =
        property_set.PropertyAt(i);
    property_set_->AddRespectingCascade(
        CSSPropertyValue(property.PropertyMetadata(), property.Value()));
  }
}

void ViewportStyleResolver::Resolve() {
  if (!property_set_) {
    document_->GetViewportData().SetViewportDescription(
        ViewportDescription(ViewportDescription::kUserAgentStyleSheet));
    return;
  }

  ViewportDescription description(
      has_author_style_ ? ViewportDescription::kAuthorStyleSheet
                        : ViewportDescription::kUserAgentStyleSheet);

  description.user_zoom = ViewportArgumentValue(CSSPropertyUserZoom);
  description.zoom = ViewportArgumentValue(CSSPropertyZoom);
  description.min_zoom = ViewportArgumentValue(CSSPropertyMinZoom);
  description.max_zoom = ViewportArgumentValue(CSSPropertyMaxZoom);
  description.min_width = ViewportLengthValue(CSSPropertyMinWidth);
  description.max_width = ViewportLengthValue(CSSPropertyMaxWidth);
  description.min_height = ViewportLengthValue(CSSPropertyMinHeight);
  description.max_height = ViewportLengthValue(CSSPropertyMaxHeight);
  description.orientation = ViewportArgumentValue(CSSPropertyOrientation);
  if (HasViewportFitProperty(property_set_))
    description.SetViewportFit(ViewportFitValue());

  document_->GetViewportData().SetViewportDescription(description);

  DCHECK(initial_style_);
  if (initial_style_->HasViewportUnits())
    has_viewport_units_ = true;
}

float ViewportStyleResolver::ViewportArgumentValue(CSSPropertyID id) const {
  float default_value = ViewportDescription::kValueAuto;

  // UserZoom default value is CSSValueZoom, which maps to true, meaning that
  // yes, it is user scalable. When the value is set to CSSValueFixed, we
  // return false.
  if (id == CSSPropertyUserZoom)
    default_value = 1;

  const CSSValue* value = property_set_->GetPropertyCSSValue(id);
  if (!value || !(value->IsPrimitiveValue() || value->IsIdentifierValue()))
    return default_value;

  if (value->IsIdentifierValue()) {
    switch (ToCSSIdentifierValue(value)->GetValueID()) {
      case CSSValueAuto:
        return default_value;
      case CSSValueLandscape:
        return ViewportDescription::kValueLandscape;
      case CSSValuePortrait:
        return ViewportDescription::kValuePortrait;
      case CSSValueZoom:
        return default_value;
      case CSSValueInternalExtendToZoom:
        return ViewportDescription::kValueExtendToZoom;
      case CSSValueFixed:
        return 0;
      default:
        return default_value;
    }
  }

  const CSSPrimitiveValue* primitive_value = ToCSSPrimitiveValue(value);

  if (primitive_value->IsNumber() || primitive_value->IsPx())
    return primitive_value->GetFloatValue();

  if (primitive_value->IsFontRelativeLength()) {
    return primitive_value->GetFloatValue() *
           initial_style_->GetFontDescription().ComputedSize();
  }

  if (primitive_value->IsPercentage()) {
    float percent_value = primitive_value->GetFloatValue() / 100.0f;
    switch (id) {
      case CSSPropertyMaxZoom:
      case CSSPropertyMinZoom:
      case CSSPropertyZoom:
        return percent_value;
      default:
        NOTREACHED();
        break;
    }
  }

  NOTREACHED();
  return default_value;
}

Length ViewportStyleResolver::ViewportLengthValue(CSSPropertyID id) {
  DCHECK(id == CSSPropertyMaxHeight || id == CSSPropertyMinHeight ||
         id == CSSPropertyMaxWidth || id == CSSPropertyMinWidth);

  const CSSValue* value = property_set_->GetPropertyCSSValue(id);
  if (!value || !(value->IsPrimitiveValue() || value->IsIdentifierValue()))
    return Length();  // auto

  if (value->IsIdentifierValue()) {
    CSSValueID value_id = ToCSSIdentifierValue(value)->GetValueID();
    if (value_id == CSSValueInternalExtendToZoom)
      return Length::ExtendToZoom();
    if (value_id == CSSValueAuto)
      return Length::Auto();
  }

  const CSSPrimitiveValue* primitive_value = ToCSSPrimitiveValue(value);

  LocalFrameView* view = document_->GetFrame()->View();
  DCHECK(view);

  CSSToLengthConversionData::FontSizes font_sizes(initial_style_.get(),
                                                  initial_style_.get());
  CSSToLengthConversionData::ViewportSize viewport_size(
      view->InitialViewportWidth(), view->InitialViewportHeight());

  Length result = primitive_value->ConvertToLength(CSSToLengthConversionData(
      initial_style_.get(), font_sizes, viewport_size, 1.0f));

  if (result.IsFixed() && document_->GetPage()) {
    float scaled_value =
        document_->GetPage()->GetChromeClient().WindowToViewportScalar(
            result.GetFloatValue());
    result = Length::Fixed(scaled_value);
  }
  return result;
}

mojom::ViewportFit ViewportStyleResolver::ViewportFitValue() const {
  const CSSValue* value =
      property_set_->GetPropertyCSSValue(CSSPropertyViewportFit);
  if (value->IsIdentifierValue()) {
    switch (ToCSSIdentifierValue(value)->GetValueID()) {
      case CSSValueCover:
        return mojom::ViewportFit::kCover;
      case CSSValueContain:
        return mojom::ViewportFit::kContain;
      case CSSValueAuto:
      default:
        return mojom::ViewportFit::kAuto;
    }
  }

  NOTREACHED();
  return mojom::ViewportFit::kAuto;
}

void ViewportStyleResolver::InitialStyleChanged() {
  initial_style_ = nullptr;
  // We need to recollect if the initial font size changed and media queries
  // depend on font relative lengths.
  needs_update_ = kCollectRules;
}

void ViewportStyleResolver::InitialViewportChanged() {
  if (needs_update_ == kCollectRules)
    return;
  if (has_viewport_units_)
    needs_update_ = kResolve;

  auto& results = viewport_dependent_media_query_results_;
  for (unsigned i = 0; i < results.size(); i++) {
    if (initial_viewport_medium_->Eval(results[i].Expression()) !=
        results[i].Result()) {
      needs_update_ = kCollectRules;
      break;
    }
  }
  if (needs_update_ == kNoUpdate)
    return;
  document_->ScheduleLayoutTreeUpdateIfNeeded();
}

void ViewportStyleResolver::SetNeedsCollectRules() {
  needs_update_ = kCollectRules;
  document_->ScheduleLayoutTreeUpdateIfNeeded();
}

void ViewportStyleResolver::UpdateViewport(
    DocumentStyleSheetCollection& collection) {
  if (needs_update_ == kNoUpdate) {
    // If initial_style_ is cleared it means things are dirty, so we should not
    // end up here.
    DCHECK(initial_style_);
    return;
  }
  if (!initial_style_)
    initial_style_ = StyleResolver::StyleForViewport(*document_);
  if (needs_update_ == kCollectRules) {
    Reset();
    CollectViewportRulesFromUASheets();
    if (RuntimeEnabledFeatures::CSSViewportEnabled())
      collection.CollectViewportRules(*this);
  }
  Resolve();
  needs_update_ = kNoUpdate;
}

void ViewportStyleResolver::Trace(blink::Visitor* visitor) {
  visitor->Trace(document_);
  visitor->Trace(property_set_);
  visitor->Trace(initial_viewport_medium_);
}

}  // namespace blink
