// Copyright 2016 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 "components/ui_devtools/css_agent.h"

#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "components/ui_devtools/agent_util.h"
#include "components/ui_devtools/ui_element.h"

namespace ui_devtools {

namespace CSS = protocol::CSS;
using protocol::Array;
using protocol::Response;

namespace {

const char kHeight[] = "height";
const char kWidth[] = "width";
const char kX[] = "x";
const char kY[] = "y";
const char kVisibility[] = "visibility";

std::unique_ptr<CSS::SourceRange> BuildDefaultPropertySourceRange() {
  // These tell the frontend where in the stylesheet a certain style
  // is located. Since we don't have stylesheets, this is all 0.
  // We need this because CSS fields are not editable unless
  // the range is provided.
  return CSS::SourceRange::create()
      .setStartLine(0)
      .setEndLine(0)
      .setStartColumn(0)
      .setEndColumn(0)
      .build();
}

std::unique_ptr<CSS::SourceRange> BuildDefaultSelectorSourceRange() {
  // This is a different source range from BuildDefaultPropertySourceRange()
  // used for the Selectors, so the frontend correctly handles property edits.
  return CSS::SourceRange::create()
      .setStartLine(1)
      .setEndLine(0)
      .setStartColumn(0)
      .setEndColumn(0)
      .build();
}

std::unique_ptr<Array<int>> BuildDefaultMatchingSelectors() {
  auto matching_selectors = std::make_unique<Array<int>>();

  // Add index 0 to matching delectors array, so frontend uses the class mame
  // from the selectors array as the header for the properties section
  matching_selectors->emplace_back(0);
  return matching_selectors;
}

std::unique_ptr<CSS::CSSProperty> BuildCSSProperty(const std::string& name,
                                                   const std::string& value) {
  return CSS::CSSProperty::create()
      .setRange(BuildDefaultPropertySourceRange())
      .setName(name)
      .setValue(value)
      .build();
}

std::unique_ptr<Array<CSS::CSSProperty>> BuildCSSProperties(
    const std::vector<UIElement::UIProperty>& properties_vector) {
  auto css_properties = std::make_unique<Array<CSS::CSSProperty>>();
  for (const auto& property : properties_vector) {
    css_properties->emplace_back(
        BuildCSSProperty(property.name_, property.value_));
  }
  return css_properties;
}

std::unique_ptr<CSS::CSSStyle> BuildCSSStyle(
    std::string stylesheet_uid,
    const std::vector<UIElement::UIProperty>& properties) {
  return CSS::CSSStyle::create()
      .setRange(BuildDefaultPropertySourceRange())
      .setCssProperties(BuildCSSProperties(properties))
      .setShorthandEntries(std::make_unique<Array<CSS::ShorthandEntry>>())
      .setStyleSheetId(stylesheet_uid)
      .build();
}

std::unique_ptr<Array<CSS::Value>> BuildSelectors(const std::string& name) {
  auto selectors = std::make_unique<Array<CSS::Value>>();
  selectors->emplace_back(CSS::Value::create()
                              .setText(name)
                              .setRange(BuildDefaultSelectorSourceRange())
                              .build());
  return selectors;
}

std::unique_ptr<CSS::SelectorList> BuildSelectorList(const std::string& name) {
  return CSS::SelectorList::create().setSelectors(BuildSelectors(name)).build();
}

std::unique_ptr<CSS::CSSRule> BuildCSSRule(
    std::string stylesheet_uid,
    const UIElement::ClassProperties& class_properties) {
  return CSS::CSSRule::create()
      .setStyleSheetId(stylesheet_uid)
      .setSelectorList(BuildSelectorList(class_properties.class_name_))
      .setStyle(BuildCSSStyle(stylesheet_uid, class_properties.properties_))
      .build();
}

std::vector<UIElement::ClassProperties> GetClassPropertiesWithBounds(
    UIElement* ui_element) {
  std::vector<UIElement::ClassProperties> properties_vector =
      ui_element->GetCustomPropertiesForMatchedStyle();

  // If GetCustomPropertiesForMatchedStyle not overridden to return custom
  // properties, populate vector with bounds properties.
  if (properties_vector.empty()) {
    gfx::Rect bounds;
    ui_element->GetBounds(&bounds);
    std::vector<UIElement::UIProperty> bound_properties;
    bound_properties.emplace_back(kX, base::NumberToString(bounds.x()));
    bound_properties.emplace_back(kY, base::NumberToString(bounds.y()));
    bound_properties.emplace_back(kWidth, base::NumberToString(bounds.width()));
    bound_properties.emplace_back(kHeight,
                                  base::NumberToString(bounds.height()));
    if (ui_element->type() != VIEW) {
      bool visible;
      ui_element->GetVisible(&visible);
      bound_properties.emplace_back(kVisibility, visible ? "true" : "false");
    }
    properties_vector.emplace_back(ui_element->GetTypeName(), bound_properties);
  }

  // Set base stylesheet ID to the last index in the vector, so when bounds
  // properties are modified, CSSAgent can update and return the right
  // properties section
  ui_element->SetBaseStylesheetId(properties_vector.size() - 1);
  return properties_vector;
}

std::string BuildStylesheetUId(int node_id, int stylesheet_id) {
  return base::NumberToString(node_id) + "_" +
         base::NumberToString(stylesheet_id);
}

Response NodeNotFoundError(int node_id) {
  return Response::Error("Node with id=" + std::to_string(node_id) +
                         " not found");
}

Response ParseProperties(const std::string& style_text,
                         gfx::Rect* bounds,
                         bool* visible) {
  std::vector<std::string> tokens = base::SplitString(
      style_text, ":;", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);

  if (tokens.size() < 2 || tokens.size() % 2 != 0)
    return Response::Error("Need both a property name and value.");

  for (size_t i = 0; i < tokens.size() - 1; i += 2) {
    const std::string& property = tokens.at(i);
    int value;
    if (!base::StringToInt(tokens.at(i + 1), &value)) {
      return Response::Error("Unable to parse value for property=" + property);
    }

    if (property == kHeight)
      bounds->set_height(std::max(0, value));
    else if (property == kWidth)
      bounds->set_width(std::max(0, value));
    else if (property == kX)
      bounds->set_x(value);
    else if (property == kY)
      bounds->set_y(value);
    else if (property == kVisibility)
      *visible = std::max(0, value) == 1;
    else
      return Response::Error("Unsupported property=" + property);
  }
  return Response::OK();
}

std::unique_ptr<CSS::CSSStyleSheetHeader> BuildObjectForStyleSheetInfo(
    std::string stylesheet_uid,
    std::string url_path,
    int line) {
  std::unique_ptr<CSS::CSSStyleSheetHeader> result =
      CSS::CSSStyleSheetHeader::create()
          .setStyleSheetId(stylesheet_uid)
          .setSourceURL(kChromiumCodeSearchSrcURL + url_path +
                        "?l=" + base::NumberToString(line))
          .setStartLine(line)
          .setStartColumn(0)
          .build();
  return result;
}

}  // namespace

CSSAgent::CSSAgent(DOMAgent* dom_agent) : dom_agent_(dom_agent) {
  DCHECK(dom_agent_);
}

CSSAgent::~CSSAgent() {
  disable();
}

Response CSSAgent::enable() {
  dom_agent_->AddObserver(this);
  return Response::OK();
}

Response CSSAgent::disable() {
  dom_agent_->RemoveObserver(this);
  return Response::OK();
}

Response CSSAgent::getMatchedStylesForNode(
    int node_id,
    protocol::Maybe<Array<CSS::RuleMatch>>* matched_css_rules) {
  UIElement* ui_element = dom_agent_->GetElementFromNodeId(node_id);
  if (!ui_element)
    return NodeNotFoundError(node_id);
  *matched_css_rules = BuildMatchedStyles(ui_element);
  return Response::OK();
}

Response CSSAgent::getStyleSheetText(const protocol::String& style_sheet_id,
                                     protocol::String* result) {
  int node_id;
  int stylesheet_id;
  std::vector<std::string> ids = base::SplitString(
      style_sheet_id, "_", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
  if (ids.size() < 2 || !base::StringToInt(ids[0], &node_id) ||
      !base::StringToInt(ids[1], &stylesheet_id))
    return Response::Error("Invalid stylesheet id");

  UIElement* ui_element = dom_agent_->GetElementFromNodeId(node_id);
  if (!ui_element)
    return Response::Error("Node id not found");

  auto sources = ui_element->GetSources();
  if (static_cast<int>(sources.size()) <= stylesheet_id)
    return Response::Error("Stylesheet id not found");

  if (GetSourceCode(sources[stylesheet_id].path_, result))
    return Response::OK();
  return Response::Error("Could not read source file");
}

Response CSSAgent::setStyleTexts(
    std::unique_ptr<Array<CSS::StyleDeclarationEdit>> edits,
    std::unique_ptr<Array<CSS::CSSStyle>>* result) {
  auto updated_styles = std::make_unique<Array<CSS::CSSStyle>>();
  for (const auto& edit : *edits) {
    int node_id;
    int stylesheet_id;

    std::vector<std::string> ids =
        base::SplitString(edit->getStyleSheetId(), "_", base::TRIM_WHITESPACE,
                          base::SPLIT_WANT_NONEMPTY);
    if (ids.size() < 2 || !base::StringToInt(ids[0], &node_id) ||
        !base::StringToInt(ids[1], &stylesheet_id))
      return Response::Error("Invalid stylesheet id");

    UIElement* ui_element = dom_agent_->GetElementFromNodeId(node_id);

    if (!ui_element)
      return Response::Error("Node id not found");
    // Handle setting properties from metadata for View.
    if (ui_element->type() == VIEW)
      ui_element->SetPropertiesFromString(edit->getText());

    gfx::Rect updated_bounds;
    bool visible = false;
    if (!GetPropertiesForUIElement(ui_element, &updated_bounds, &visible))
      return NodeNotFoundError(node_id);

    Response response(
        ParseProperties(edit->getText(), &updated_bounds, &visible));
    if (!response.isSuccess())
      return response;

    if (!SetPropertiesForUIElement(ui_element, updated_bounds, visible))
      return NodeNotFoundError(node_id);

    updated_styles->emplace_back(BuildCSSStyle(
        edit->getStyleSheetId(), GetClassPropertiesWithBounds(ui_element)
                                     .at(stylesheet_id)
                                     .properties_));
  }
  *result = std::move(updated_styles);
  return Response::OK();
}

void CSSAgent::OnElementBoundsChanged(UIElement* ui_element) {
  InvalidateStyleSheet(ui_element);
}

void CSSAgent::InvalidateStyleSheet(UIElement* ui_element) {
  // The stylesheetId for each node is equivalent to a string of its
  // node_id + "_" + index of CSS::RuleMatch in vector.
  frontend()->styleSheetChanged(BuildStylesheetUId(
      ui_element->node_id(), ui_element->GetBaseStylesheetId()));
}

bool CSSAgent::GetPropertiesForUIElement(UIElement* ui_element,
                                         gfx::Rect* bounds,
                                         bool* visible) {
  if (ui_element) {
    ui_element->GetBounds(bounds);
    if (ui_element->type() != VIEW)
      ui_element->GetVisible(visible);
    return true;
  }
  return false;
}

bool CSSAgent::SetPropertiesForUIElement(UIElement* ui_element,
                                         const gfx::Rect& bounds,
                                         bool visible) {
  if (ui_element) {
    ui_element->SetBounds(bounds);
    ui_element->SetVisible(visible);
    return true;
  }
  return false;
}

std::unique_ptr<Array<CSS::RuleMatch>> CSSAgent::BuildMatchedStyles(
    UIElement* ui_element) {
  auto result = std::make_unique<Array<CSS::RuleMatch>>();
  std::vector<UIElement::ClassProperties> properties_vector =
      GetClassPropertiesWithBounds(ui_element);

  for (size_t i = 0; i < properties_vector.size(); i++) {
    result->emplace_back(
        CSS::RuleMatch::create()
            .setRule(BuildCSSRule(BuildStylesheetUId(ui_element->node_id(), i),
                                  properties_vector[i]))
            .setMatchingSelectors(BuildDefaultMatchingSelectors())
            .build());
  }
  if (!ui_element->header_sent()) {
    InitStylesheetHeaders(ui_element);
  }
  return result;
}

void CSSAgent::InitStylesheetHeaders(UIElement* ui_element) {
  std::vector<UIElement::Source> sources = ui_element->GetSources();
  for (size_t i = 0; i < sources.size(); i++) {
    frontend()->styleSheetAdded(BuildObjectForStyleSheetInfo(
        BuildStylesheetUId(ui_element->node_id(), i), sources[i].path_,
        sources[i].line_));
  }
  ui_element->set_header_sent();
}

}  // namespace ui_devtools
