// 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_number_conversions.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::ServerError("Node with id=" + base::NumberToString(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::ServerError("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::ServerError("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::ServerError("Unsupported property=" + property);
  }
  return Response::Success();
}

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::Success();
}

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

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::Success();
}

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::ServerError("Invalid stylesheet id");

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

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

  if (GetSourceCode(sources[stylesheet_id].path_, result))
    return Response::Success();
  return Response::ServerError("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::ServerError("Invalid stylesheet id");

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

    if (!ui_element)
      return Response::ServerError("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::Success();
}

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
