// Copyright 2016 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/cssom/css_declared_style_declaration.h"

#include "base/lazy_instance.h"
#include "base/trace_event/trace_event.h"
#include "cobalt/cssom/css_declared_style_data.h"
#include "cobalt/cssom/css_parser.h"
#include "cobalt/cssom/mutation_observer.h"

namespace cobalt {
namespace cssom {

namespace {

struct NonTrivialStaticFields {
  NonTrivialStaticFields()
      : location(base::SourceLocation(
            CSSStyleDeclaration::GetSourceLocationName(), 1, 1)) {}

  const base::SourceLocation location;

 private:
  DISALLOW_COPY_AND_ASSIGN(NonTrivialStaticFields);
};

// |non_trivial_static_fields| will be lazily created on the first time it's
// accessed.
base::LazyInstance<NonTrivialStaticFields>::DestructorAtExit
    non_trivial_static_fields = LAZY_INSTANCE_INITIALIZER;

}  // namespace

CSSDeclaredStyleDeclaration::CSSDeclaredStyleDeclaration(CSSParser* css_parser)
    : css_parser_(css_parser), mutation_observer_(NULL) {}

CSSDeclaredStyleDeclaration::CSSDeclaredStyleDeclaration(
    const scoped_refptr<CSSDeclaredStyleData>& data, CSSParser* css_parser)
    : data_(data), css_parser_(css_parser), mutation_observer_(NULL) {
  DCHECK(data_.get());
}

// This returns the result of serializing a CSS declaration block.
// The current implementation does not handle shorthands.
//   https://www.w3.org/TR/cssom/#serialize-a-css-declaration-block
std::string CSSDeclaredStyleDeclaration::css_text(
    script::ExceptionState* /*exception_state*/) const {
  return data_ ? data_->SerializeCSSDeclarationBlock() : std::string();
}

void CSSDeclaredStyleDeclaration::set_css_text(
    const std::string& css_text, script::ExceptionState* /*exception_state*/) {
  TRACE_EVENT0("cobalt::cssom", "CSSDeclaredStyleDeclaration::set_css_text");
  DCHECK(css_parser_);
  scoped_refptr<CSSDeclaredStyleData> declaration =
      css_parser_->ParseStyleDeclarationList(
          css_text, non_trivial_static_fields.Get().location);

  bool changed = true;

  if (declaration) {
    if (data_ && *data_ == *declaration) {
      changed = false;
    }
    data_ = declaration;
  } else {
    if (!data_) {
      changed = false;
    }
    data_ = NULL;
  }

  if (changed) {
    RecordMutation();
  }
}

// The length attribute must return the number of CSS declarations in the
// declarations.
//   https://www.w3.org/TR/cssom/#dom-cssstyledeclaration-length
unsigned int CSSDeclaredStyleDeclaration::length() const {
  return data_ ? data_->length() : 0;
}

// The item(index) method must return the property name of the CSS declaration
// at position index.
//   https://www.w3.org/TR/cssom/#dom-cssstyledeclaration-item
base::Optional<std::string> CSSDeclaredStyleDeclaration::Item(
    unsigned int index) const {
  const char* item = data_ ? data_->Item(index) : NULL;
  return item ? base::Optional<std::string>(item) : base::nullopt;
}

std::string CSSDeclaredStyleDeclaration::GetDeclaredPropertyValueStringByKey(
    const PropertyKey key) const {
  if (key > kMaxLonghandPropertyKey) {
    // Shorthand properties are never directly stored as declared properties,
    // but are expanded into their longhand property components during parsing.
    // TODO: Implement serialization of css values, see
    // https://www.w3.org/TR/cssom-1/#serializing-css-values
    DCHECK_LE(key, kMaxEveryPropertyKey);
    NOTIMPLEMENTED();
    DLOG(WARNING) << "Unsupported property query for \"" << GetPropertyName(key)
                  << "\": Returning of property value strings is not "
                     "supported for shorthand properties.";
    return std::string();
  }
  return (data_ && key != kNoneProperty) ? data_->GetPropertyValueString(key)
                                         : std::string();
}

void CSSDeclaredStyleDeclaration::SetPropertyValue(
    const std::string& property_name, const std::string& property_value,
    script::ExceptionState* /*exception_state*/) {
  DCHECK(css_parser_);
  if (!data_) {
    data_ = new CSSDeclaredStyleData();
  }
  css_parser_->ParsePropertyIntoDeclarationData(
      property_name, property_value, non_trivial_static_fields.Get().location,
      data_.get());

  RecordMutation();
}

void CSSDeclaredStyleDeclaration::SetProperty(
    const std::string& property_name, const std::string& property_value,
    const std::string& priority, script::ExceptionState* /*exception_state*/) {
  DLOG(INFO) << "CSSDeclaredStyleDeclaration::SetProperty(" << property_name
             << "," << property_value << "," << priority << ")";
  DCHECK(css_parser_);
  if (!data_) {
    data_ = new CSSDeclaredStyleData();
  }
  css_parser_->ParsePropertyIntoDeclarationData(
      property_name, property_value, non_trivial_static_fields.Get().location,
      data_.get());

  RecordMutation();
}

void CSSDeclaredStyleDeclaration::RecordMutation() {
  if (mutation_observer_) {
    // Trigger layout update.
    mutation_observer_->OnCSSMutation();
  }
}

void CSSDeclaredStyleDeclaration::AssignFrom(
    const CSSDeclaredStyleDeclaration& rhs) {
  if (!rhs.data_) {
    data_ = NULL;
    return;
  }
  if (!data_) {
    data_ = new CSSDeclaredStyleData();
  }
  data_->AssignFrom(*rhs.data_);
}

}  // namespace cssom
}  // namespace cobalt
