// Copyright 2014 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 "extensions/common/manifest_handlers/webview_info.h"

#include "base/memory/scoped_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "extensions/common/error_utils.h"
#include "extensions/common/manifest.h"
#include "extensions/common/manifest_constants.h"

namespace extensions {

namespace keys = extensions::manifest_keys;
namespace errors = extensions::manifest_errors;

namespace {

const WebviewInfo* GetResourcesInfo(
    const Extension& extension) {
  return static_cast<WebviewInfo*>(
      extension.GetManifestData(keys::kWebviewAccessibleResources));
}

}  // namespace

// A PartitionItem represents a set of accessible resources given a partition
// ID pattern.
class PartitionItem {
 public:
  explicit PartitionItem(const std::string& partition_pattern)
      : partition_pattern_(partition_pattern) {
  }

  virtual ~PartitionItem() {
  }

  bool Matches(const std::string& partition_id) const {
    return MatchPattern(partition_id, partition_pattern_);
  }

  // Adds a pattern to the set. Returns true if a new pattern was inserted,
  // false if the pattern was already in the set.
  bool AddPattern(const URLPattern& pattern) {
    return accessible_resources_.AddPattern(pattern);
  }

  const URLPatternSet& accessible_resources() const {
    return accessible_resources_;
  }
 private:
  // A pattern string that matches partition IDs.
  const std::string partition_pattern_;
  // A URL pattern set of resources accessible to the given
  // |partition_pattern_|.
  URLPatternSet accessible_resources_;
};


WebviewInfo::WebviewInfo() {
}

WebviewInfo::~WebviewInfo() {
}

// static
bool WebviewInfo::IsResourceWebviewAccessible(
    const Extension* extension,
    const std::string& partition_id,
    const std::string& relative_path) {
  if (!extension)
    return false;

  const WebviewInfo* info = GetResourcesInfo(*extension);
  if (!info)
    return false;

  for (size_t i = 0; i < info->partition_items_.size(); ++i) {
    const PartitionItem* const item = info->partition_items_[i];
    if (item->Matches(partition_id) &&
        extension->ResourceMatches(item->accessible_resources(),
                                   relative_path)) {
      return true;
    }
  }

  return false;
}

void WebviewInfo::AddPartitionItem(scoped_ptr<PartitionItem> item) {
  partition_items_.push_back(item.release());
}

WebviewHandler::WebviewHandler() {
}

WebviewHandler::~WebviewHandler() {
}

bool WebviewHandler::Parse(Extension* extension, base::string16* error) {
  scoped_ptr<WebviewInfo> info(new WebviewInfo());

  const base::DictionaryValue* dict_value = NULL;
  if (!extension->manifest()->GetDictionary(keys::kWebview,
                                            &dict_value)) {
    *error = base::ASCIIToUTF16(errors::kInvalidWebview);
    return false;
  }

  const base::ListValue* partition_list = NULL;
  if (!dict_value->GetList(keys::kWebviewPartitions, &partition_list)) {
    *error = base::ASCIIToUTF16(errors::kInvalidWebviewPartitionsList);
    return false;
  }

  // The partition list must have at least one entry.
  if (partition_list->GetSize() == 0) {
    *error = base::ASCIIToUTF16(errors::kInvalidWebviewPartitionsList);
    return false;
  }

  for (size_t i = 0; i < partition_list->GetSize(); ++i) {
    const base::DictionaryValue* partition = NULL;
    if (!partition_list->GetDictionary(i, &partition)) {
      *error = ErrorUtils::FormatErrorMessageUTF16(
          errors::kInvalidWebviewPartition, base::IntToString(i));
      return false;
    }

    std::string partition_pattern;
    if (!partition->GetString(keys::kWebviewName, &partition_pattern)) {
      *error = ErrorUtils::FormatErrorMessageUTF16(
          errors::kInvalidWebviewPartitionName, base::IntToString(i));
      return false;
    }

    const base::ListValue* url_list = NULL;
    if (!partition->GetList(keys::kWebviewAccessibleResources,
                            &url_list)) {
      *error = base::ASCIIToUTF16(
          errors::kInvalidWebviewAccessibleResourcesList);
      return false;
    }

    // The URL list should have at least one entry.
    if (url_list->GetSize() == 0) {
      *error = base::ASCIIToUTF16(
          errors::kInvalidWebviewAccessibleResourcesList);
      return false;
    }

    scoped_ptr<PartitionItem> partition_item(
        new PartitionItem(partition_pattern));

    for (size_t i = 0; i < url_list->GetSize(); ++i) {
      std::string relative_path;
      if (!url_list->GetString(i, &relative_path)) {
        *error = ErrorUtils::FormatErrorMessageUTF16(
            errors::kInvalidWebviewAccessibleResource, base::IntToString(i));
        return false;
      }
      URLPattern pattern(URLPattern::SCHEME_EXTENSION,
                         Extension::GetResourceURL(extension->url(),
                                                   relative_path).spec());
      partition_item->AddPattern(pattern);
    }
    info->AddPartitionItem(partition_item.Pass());
  }

  extension->SetManifestData(keys::kWebviewAccessibleResources, info.release());
  return true;
}

const std::vector<std::string> WebviewHandler::Keys() const {
  return SingleKey(keys::kWebview);
}

}  // namespace extensions
