/*
 * 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 "core/css/resolver/ViewportStyleResolver.h"

#include "core/CSSValueKeywords.h"
#include "core/css/CSSDefaultStyleSheets.h"
#include "core/css/CSSPrimitiveValueMappings.h"
#include "core/css/CSSStyleSheet.h"
#include "core/css/CSSToLengthConversionData.h"
#include "core/css/MediaValuesInitialViewport.h"
#include "core/css/StylePropertySet.h"
#include "core/css/StyleRule.h"
#include "core/css/StyleRuleImport.h"
#include "core/css/StyleSheetContents.h"
#include "core/css/resolver/ScopedStyleResolver.h"
#include "core/dom/Document.h"
#include "core/dom/DocumentStyleSheetCollection.h"
#include "core/dom/NodeComputedStyle.h"
#include "core/dom/ViewportDescription.h"
#include "core/frame/Settings.h"
#include "core/layout/api/LayoutViewItem.h"

namespace blink {

ViewportStyleResolver::ViewportStyleResolver(Document& document)
    : m_document(document) {
  DCHECK(document.frame());
  m_initialViewportMedium = new MediaQueryEvaluator(
      MediaValuesInitialViewport::create(*document.frame()));
}

void ViewportStyleResolver::reset() {
  m_viewportDependentMediaQueryResults.clear();
  m_deviceDependentMediaQueryResults.clear();
  m_propertySet = nullptr;
  m_hasAuthorStyle = false;
  m_hasViewportUnits = false;
  m_needsUpdate = NoUpdate;
}

void ViewportStyleResolver::collectViewportRulesFromUASheets() {
  CSSDefaultStyleSheets& defaultStyleSheets = CSSDefaultStyleSheets::instance();
  WebViewportStyle viewportStyle = m_document->settings()
                                       ? m_document->settings()->viewportStyle()
                                       : WebViewportStyle::Default;
  StyleSheetContents* viewportContents = nullptr;
  switch (viewportStyle) {
    case WebViewportStyle::Default:
      break;
    case WebViewportStyle::Mobile:
      viewportContents = defaultStyleSheets.ensureMobileViewportStyleSheet();
      break;
    case WebViewportStyle::Television:
      viewportContents =
          defaultStyleSheets.ensureTelevisionViewportStyleSheet();
      break;
  }
  if (viewportContents)
    collectViewportChildRules(viewportContents->childRules(), UserAgentOrigin);

  if (m_document->isMobileDocument()) {
    collectViewportChildRules(
        defaultStyleSheets.ensureXHTMLMobileProfileStyleSheet()->childRules(),
        UserAgentOrigin);
  }
  DCHECK(!defaultStyleSheets.defaultStyleSheet()->hasViewportRule());
}

void ViewportStyleResolver::collectViewportRules() {
  reset();
  collectViewportRulesFromUASheets();
  if (ScopedStyleResolver* scopedResolver = m_document->scopedStyleResolver())
    scopedResolver->collectViewportRulesTo(this);

  resolve();
}

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* mediaRule = toStyleRuleMedia(rule);
      if (!mediaRule->mediaQueries() ||
          m_initialViewportMedium->eval(mediaRule->mediaQueries(),
                                        &m_viewportDependentMediaQueryResults,
                                        &m_deviceDependentMediaQueryResults))
        collectViewportChildRules(mediaRule->childRules(), origin);
    } else if (rule->isSupportsRule()) {
      StyleRuleSupports* supportsRule = toStyleRuleSupports(rule);
      if (supportsRule->conditionIsSupported())
        collectViewportChildRules(supportsRule->childRules(), origin);
    }
  }
}

void ViewportStyleResolver::collectViewportRulesFromImports(
    StyleSheetContents& contents) {
  for (const auto& importRule : contents.importRules()) {
    if (!importRule->styleSheet())
      continue;
    if (!importRule->styleSheet()->hasViewportRule())
      continue;
    if (importRule->mediaQueries() &&
        m_initialViewportMedium->eval(importRule->mediaQueries(),
                                      &m_viewportDependentMediaQueryResults,
                                      &m_deviceDependentMediaQueryResults))
      collectViewportRulesFromAuthorSheetContents(*importRule->styleSheet());
  }
}

void ViewportStyleResolver::collectViewportRulesFromAuthorSheetContents(
    StyleSheetContents& contents) {
  collectViewportRulesFromImports(contents);
  if (contents.hasViewportRule())
    collectViewportChildRules(contents.childRules(), AuthorOrigin);
}

void ViewportStyleResolver::collectViewportRulesFromAuthorSheet(
    const CSSStyleSheet& sheet) {
  DCHECK(sheet.contents());
  StyleSheetContents& contents = *sheet.contents();
  if (!contents.hasViewportRule() && contents.importRules().isEmpty())
    return;
  if (sheet.mediaQueries() &&
      !m_initialViewportMedium->eval(sheet.mediaQueries(),
                                     &m_viewportDependentMediaQueryResults,
                                     &m_deviceDependentMediaQueryResults))
    return;
  collectViewportRulesFromAuthorSheetContents(contents);
}

void ViewportStyleResolver::collectViewportRules(RuleSet* rules,
                                                 Origin origin) {
  rules->compactRulesIfNeeded();

  const HeapVector<Member<StyleRuleViewport>>& viewportRules =
      rules->viewportRules();
  for (size_t i = 0; i < viewportRules.size(); ++i)
    addViewportRule(*viewportRules[i], origin);
}

void ViewportStyleResolver::addViewportRule(StyleRuleViewport& viewportRule,
                                            Origin origin) {
  StylePropertySet& propertySet = viewportRule.mutableProperties();

  unsigned propertyCount = propertySet.propertyCount();
  if (!propertyCount)
    return;

  if (origin == AuthorOrigin)
    m_hasAuthorStyle = true;

  if (!m_propertySet) {
    m_propertySet = propertySet.mutableCopy();
    return;
  }

  // We cannot use mergeAndOverrideOnConflict() here because it doesn't
  // respect the !important declaration (but addRespectingCascade() does).
  for (unsigned i = 0; i < propertyCount; ++i)
    m_propertySet->addRespectingCascade(
        propertySet.propertyAt(i).toCSSProperty());
}

void ViewportStyleResolver::resolve() {
  if (!m_propertySet) {
    m_document->setViewportDescription(
        ViewportDescription(ViewportDescription::UserAgentStyleSheet));
    return;
  }

  ViewportDescription description(
      m_hasAuthorStyle ? ViewportDescription::AuthorStyleSheet
                       : ViewportDescription::UserAgentStyleSheet);

  description.userZoom = viewportArgumentValue(CSSPropertyUserZoom);
  description.zoom = viewportArgumentValue(CSSPropertyZoom);
  description.minZoom = viewportArgumentValue(CSSPropertyMinZoom);
  description.maxZoom = viewportArgumentValue(CSSPropertyMaxZoom);
  description.minWidth = viewportLengthValue(CSSPropertyMinWidth);
  description.maxWidth = viewportLengthValue(CSSPropertyMaxWidth);
  description.minHeight = viewportLengthValue(CSSPropertyMinHeight);
  description.maxHeight = viewportLengthValue(CSSPropertyMaxHeight);
  description.orientation = viewportArgumentValue(CSSPropertyOrientation);

  m_document->setViewportDescription(description);
}

float ViewportStyleResolver::viewportArgumentValue(CSSPropertyID id) const {
  float defaultValue = ViewportDescription::ValueAuto;

  // 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)
    defaultValue = 1;

  const CSSValue* value = m_propertySet->getPropertyCSSValue(id);
  if (!value || !(value->isPrimitiveValue() || value->isIdentifierValue()))
    return defaultValue;

  if (value->isIdentifierValue()) {
    switch (toCSSIdentifierValue(value)->getValueID()) {
      case CSSValueAuto:
        return defaultValue;
      case CSSValueLandscape:
        return ViewportDescription::ValueLandscape;
      case CSSValuePortrait:
        return ViewportDescription::ValuePortrait;
      case CSSValueZoom:
        return defaultValue;
      case CSSValueInternalExtendToZoom:
        return ViewportDescription::ValueExtendToZoom;
      case CSSValueFixed:
        return 0;
      default:
        return defaultValue;
    }
  }

  const CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);

  if (primitiveValue->isNumber() || primitiveValue->isPx())
    return primitiveValue->getFloatValue();

  if (primitiveValue->isFontRelativeLength())
    return primitiveValue->getFloatValue() *
           m_document->computedStyle()->getFontDescription().computedSize();

  if (primitiveValue->isPercentage()) {
    float percentValue = primitiveValue->getFloatValue() / 100.0f;
    switch (id) {
      case CSSPropertyMaxZoom:
      case CSSPropertyMinZoom:
      case CSSPropertyZoom:
        return percentValue;
      default:
        NOTREACHED();
        break;
    }
  }

  NOTREACHED();
  return defaultValue;
}

Length ViewportStyleResolver::viewportLengthValue(CSSPropertyID id) {
  ASSERT(id == CSSPropertyMaxHeight || id == CSSPropertyMinHeight ||
         id == CSSPropertyMaxWidth || id == CSSPropertyMinWidth);

  const CSSValue* value = m_propertySet->getPropertyCSSValue(id);
  if (!value || !(value->isPrimitiveValue() || value->isIdentifierValue()))
    return Length();  // auto

  if (value->isIdentifierValue()) {
    CSSValueID valueID = toCSSIdentifierValue(value)->getValueID();
    if (valueID == CSSValueInternalExtendToZoom)
      return Length(ExtendToZoom);
    if (valueID == CSSValueAuto)
      return Length(Auto);
  }

  const CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
  ComputedStyle* documentStyle = m_document->mutableComputedStyle();

  // If we have viewport units the conversion will mark the document style as
  // having viewport units.
  bool documentStyleHasViewportUnits = documentStyle->hasViewportUnits();
  documentStyle->setHasViewportUnits(false);

  CSSToLengthConversionData::FontSizes fontSizes(documentStyle, documentStyle);
  CSSToLengthConversionData::ViewportSize viewportSize(
      m_document->layoutViewItem());

  Length result = primitiveValue->convertToLength(
      CSSToLengthConversionData(documentStyle, fontSizes, viewportSize, 1.0f));
  if (documentStyle->hasViewportUnits()) {
    // TODO (rune@opera.com): remove the setHasViewportUnit when
    // initialViewportChanged() goes live.
    m_document->setHasViewportUnits();
    m_hasViewportUnits = true;
  }
  documentStyle->setHasViewportUnits(documentStyleHasViewportUnits);

  return result;
}

void ViewportStyleResolver::initialViewportChanged() {
  if (m_needsUpdate == CollectRules)
    return;

  auto& results = m_viewportDependentMediaQueryResults;
  for (unsigned i = 0; i < results.size(); i++) {
    if (m_initialViewportMedium->eval(results[i]->expression()) !=
        results[i]->result()) {
      m_needsUpdate = CollectRules;
      return;
    }
  }
  if (m_hasViewportUnits)
    m_needsUpdate = Resolve;
}

void ViewportStyleResolver::setNeedsCollectRules() {
  m_needsUpdate = CollectRules;
}

void ViewportStyleResolver::updateViewport(
    DocumentStyleSheetCollection& collection) {
  if (m_needsUpdate == NoUpdate)
    return;
  if (m_needsUpdate == CollectRules) {
    reset();
    collectViewportRulesFromUASheets();
    if (RuntimeEnabledFeatures::cssViewportEnabled())
      collection.collectViewportRules(*this);
  }
  resolve();
  m_needsUpdate = NoUpdate;
}

DEFINE_TRACE(ViewportStyleResolver) {
  visitor->trace(m_document);
  visitor->trace(m_propertySet);
  visitor->trace(m_initialViewportMedium);
  visitor->trace(m_viewportDependentMediaQueryResults);
  visitor->trace(m_deviceDependentMediaQueryResults);
}

}  // namespace blink
