// Copyright (c) 2012 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 "chrome/common/content_settings_pattern_parser.h"

#include "base/strings/string_util.h"
#include "chrome/common/url_constants.h"
#include "extensions/common/constants.h"
#include "net/base/net_util.h"
#include "url/gurl.h"
#include "url/url_canon.h"

namespace {

const char* kUrlPathSeparator = "/";
const char* kUrlPortSeparator = ":";

class Component {
 public:
  Component() : start(0), len(0) {}
  Component(size_t s, size_t l) : start(s), len(l) {}

  bool IsNonEmpty() {
    return len > 0;
  }

  size_t start;
  size_t len;
};

}  // namespace

namespace content_settings {

const char* PatternParser::kDomainWildcard = "[*.]";

const size_t PatternParser::kDomainWildcardLength = 4;

const char* PatternParser::kSchemeWildcard = "*";

const char* PatternParser::kHostWildcard = "*";

const char* PatternParser::kPortWildcard = "*";

const char* PatternParser::kPathWildcard = "*";

// static
void PatternParser::Parse(const std::string& pattern_spec,
                          ContentSettingsPattern::BuilderInterface* builder) {
  if (pattern_spec == "*") {
    builder->WithSchemeWildcard();
    builder->WithDomainWildcard();
    builder->WithPortWildcard();
    return;
  }

  // Initialize components for the individual patterns parts to empty
  // sub-strings.
  Component scheme_component;
  Component host_component;
  Component port_component;
  Component path_component;

  size_t start = 0;
  size_t current_pos = 0;

  if (pattern_spec.empty())
    return;

  // Test if a scheme pattern is in the spec.
  current_pos = pattern_spec.find(
      std::string(content::kStandardSchemeSeparator), start);
  if (current_pos != std::string::npos) {
    scheme_component = Component(start, current_pos);
    start = current_pos + strlen(content::kStandardSchemeSeparator);
    current_pos = start;
  } else {
    current_pos = start;
  }

  if (start >= pattern_spec.size())
    return;  // Bad pattern spec.

  // Jump to the end of domain wildcards or an IPv6 addresses. IPv6 addresses
  // contain ':'. So first move to the end of an IPv6 address befor searching
  // for the ':' that separates the port form the host.
  if (pattern_spec[current_pos] == '[')
    current_pos = pattern_spec.find("]", start);

  if (current_pos == std::string::npos)
    return;  // Bad pattern spec.

  current_pos = pattern_spec.find(std::string(kUrlPortSeparator), current_pos);
  if (current_pos == std::string::npos) {
    // No port spec found
    current_pos = pattern_spec.find(std::string(kUrlPathSeparator), start);
    if (current_pos == std::string::npos) {
      current_pos = pattern_spec.size();
      host_component = Component(start, current_pos - start);
    } else {
      // Pattern has a path spec.
      host_component = Component(start, current_pos - start);
    }
    start = current_pos;
  } else {
    // Port spec found.
    host_component = Component(start, current_pos - start);
    start = current_pos + 1;
    if (start < pattern_spec.size()) {
      current_pos = pattern_spec.find(std::string(kUrlPathSeparator), start);
      if (current_pos == std::string::npos) {
        current_pos = pattern_spec.size();
      }
      port_component = Component(start, current_pos - start);
      start = current_pos;
    }
  }

  current_pos = pattern_spec.size();
  if (start < current_pos) {
    // Pattern has a path spec.
    path_component = Component(start, current_pos - start);
  }

  // Set pattern parts.
  std::string scheme;
  if (scheme_component.IsNonEmpty()) {
    scheme = pattern_spec.substr(scheme_component.start, scheme_component.len);
    if (scheme == kSchemeWildcard) {
      builder->WithSchemeWildcard();
    } else {
      builder->WithScheme(scheme);
    }
  } else {
    builder->WithSchemeWildcard();
  }

  if (host_component.IsNonEmpty()) {
    std::string host = pattern_spec.substr(host_component.start,
                                           host_component.len);
    if (host == kHostWildcard) {
      builder->WithDomainWildcard();
    } else if (StartsWithASCII(host, kDomainWildcard, true)) {
      host = host.substr(kDomainWildcardLength);
      builder->WithDomainWildcard();
      builder->WithHost(host);
    } else {
      // If the host contains a wildcard symbol then it is invalid.
      if (host.find(kHostWildcard) != std::string::npos) {
        builder->Invalid();
        return;
      }
      builder->WithHost(host);
    }
  }

  if (port_component.IsNonEmpty()) {
    const std::string port = pattern_spec.substr(port_component.start,
                                                 port_component.len);
    if (port == kPortWildcard) {
      builder->WithPortWildcard();
    } else {
      // Check if the port string represents a valid port.
      for (size_t i = 0; i < port.size(); ++i) {
        if (!IsAsciiDigit(port[i])) {
          builder->Invalid();
          return;
        }
      }
      // TODO(markusheintz): Check port range.
      builder->WithPort(port);
    }
  } else {
    if (scheme != std::string(extensions::kExtensionScheme) &&
        scheme != std::string(chrome::kFileScheme))
      builder->WithPortWildcard();
  }

  if (path_component.IsNonEmpty()) {
    const std::string path = pattern_spec.substr(path_component.start,
                                                 path_component.len);
    if (path.substr(1) == kPathWildcard)
      builder->WithPathWildcard();
    else
      builder->WithPath(path);
  }
}

// static
std::string PatternParser::ToString(
    const ContentSettingsPattern::PatternParts& parts) {
  // Return the most compact form to support legacy code and legacy pattern
  // strings.
  if (parts.is_scheme_wildcard &&
      parts.has_domain_wildcard &&
      parts.host.empty() &&
      parts.is_port_wildcard)
    return "*";

  std::string str;
  if (!parts.is_scheme_wildcard)
    str += parts.scheme + content::kStandardSchemeSeparator;

  if (parts.scheme == chrome::kFileScheme) {
    if (parts.is_path_wildcard)
      return str + kUrlPathSeparator + kPathWildcard;
    else
      return str + parts.path;
  }

  if (parts.has_domain_wildcard) {
    if (parts.host.empty())
      str += kHostWildcard;
    else
      str += kDomainWildcard;
  }
  str += parts.host;

  if (parts.scheme == std::string(extensions::kExtensionScheme)) {
    str += parts.path.empty() ? std::string(kUrlPathSeparator) : parts.path;
    return str;
  }

  if (!parts.is_port_wildcard) {
    str += std::string(kUrlPortSeparator) + parts.port;
  }

  return str;
}

}  // namespace content_settings
