// Copyright 2015 Google Inc. 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/webdriver/protocol/capabilities.h"

#include "base/memory/scoped_ptr.h"
#include "base/values.h"
#include "cobalt/version.h"

namespace cobalt {
namespace webdriver {
namespace protocol {
namespace {

const char kBrowserNameKey[] = "browserName";
const char kVersionKey[] = "version";
const char kPlatformKey[] = "platform";
const char kJavascriptEnabledKey[] = "javascriptEnabled";
const char kTakesScreenshotKey[] = "takesScreenshot";
const char kHandlesAlertsKey[] = "handlesAlerts";
const char kDatabaseEnabled[] = "databaseEnabled";
const char kLocationContextEnabledKey[] = "locationContextEnabled";
const char kApplicationCacheEnabledKey[] = "applicationCacheEnabled";
const char kBrowserConnectionEnabledKey[] = "browserConnectionEnabled";
const char kCssSelectorsEnabledKey[] = "cssSelectorsEnabled";
const char kWebStorageEnabledKey[] = "webStorageEnabled";
const char kRotatableKey[] = "rotatable";
const char kAcceptSslCertsKey[] = "acceptSslCerts";
const char kNativeEventsKey[] = "nativeEvents";
const char kProxyKey[] = "proxy";

const char kDesiredCapabilitiesKey[] = "desiredCapabilities";
const char kRequiredCapabilitiesKey[] = "requiredCapabilities";

// Helper class for reading from the base::DictionaryValue representing
// capabilities from the client into a Capabilities object.
// This will parse a capability and set its corresponding member in the
// Capabilities object, and then remove the handled capability from the
// source base::DictionaryValue.
class CapabilityReader {
 public:
  CapabilityReader(Capabilities* capabilities,
                   base::DictionaryValue* capabilities_value)
      : capabilities_(capabilities), capabilities_value_(capabilities_value) {}

  template <base::optional<std::string> Capabilities::*member>
  void TryReadCapability(const char* key) {
    std::string value;
    if (capabilities_value_->GetString(key, &value)) {
      (capabilities_->*member) = value;
      bool removed = capabilities_value_->Remove(key, NULL);
      DCHECK(removed);
    }
  }

  template <base::optional<bool> Capabilities::*member>
  void TryReadCapability(const char* key) {
    bool value;
    if (capabilities_value_->GetBoolean(key, &value)) {
      (capabilities_->*member) = value;
      bool removed = capabilities_value_->Remove(key, NULL);
      DCHECK(removed);
    }
  }

  template <typename T, base::optional<T> Capabilities::*member>
  void TryReadCapability(const char* key) {
    const base::DictionaryValue* dictionary_value;
    if (capabilities_value_->GetDictionary(key, &dictionary_value)) {
      (capabilities_->*member) = T::FromValue(dictionary_value);
      if (capabilities_->*member) {
        bool removed = capabilities_value_->Remove(key, NULL);
        DCHECK(removed);
      }
    }
  }

 private:
  Capabilities* capabilities_;
  base::DictionaryValue* capabilities_value_;
};

class CapabilityWriter {
 public:
  CapabilityWriter(const Capabilities& capabilities,
                   base::DictionaryValue* capabilities_value)
      : capabilities_(capabilities), capabilities_value_(capabilities_value) {}

  template <base::optional<std::string> Capabilities::*member>
  void TryWriteCapability(const char* key) {
    if (capabilities_.*member) {
      capabilities_value_->SetString(key, (capabilities_.*member).value());
    }
  }

  template <base::optional<bool> Capabilities::*member>
  void TryWriteCapability(const char* key) {
    if (capabilities_.*member) {
      capabilities_value_->SetBoolean(key, (capabilities_.*member).value());
    }
  }

 private:
  const Capabilities& capabilities_;
  base::DictionaryValue* capabilities_value_;
};

}  // namespace

scoped_ptr<base::Value> Capabilities::ToValue(
    const Capabilities& capabilities) {
  scoped_ptr<base::DictionaryValue> capabilities_value(
      new base::DictionaryValue());

  CapabilityWriter writer(capabilities, capabilities_value.get());
  // Write all the capabilities that have been set.
  writer.TryWriteCapability<&Capabilities::browser_name_>(kBrowserNameKey);
  writer.TryWriteCapability<&Capabilities::version_>(kVersionKey);
  writer.TryWriteCapability<&Capabilities::platform_>(kPlatformKey);
  writer.TryWriteCapability<&Capabilities::javascript_enabled_>(
      kJavascriptEnabledKey);
  writer.TryWriteCapability<&Capabilities::takes_screenshot_>(
      kTakesScreenshotKey);
  writer.TryWriteCapability<&Capabilities::handles_alerts_>(kHandlesAlertsKey);
  writer.TryWriteCapability<&Capabilities::database_enabled_>(kDatabaseEnabled);
  writer.TryWriteCapability<&Capabilities::location_context_enabled_>(
      kLocationContextEnabledKey);
  writer.TryWriteCapability<&Capabilities::application_cache_enabled_>(
      kApplicationCacheEnabledKey);
  writer.TryWriteCapability<&Capabilities::browser_connection_enabled_>(
      kBrowserConnectionEnabledKey);
  writer.TryWriteCapability<&Capabilities::css_selectors_enabled_>(
      kCssSelectorsEnabledKey);
  writer.TryWriteCapability<&Capabilities::web_storage_enabled_>(
      kWebStorageEnabledKey);
  writer.TryWriteCapability<&Capabilities::rotatable_>(kRotatableKey);
  writer.TryWriteCapability<&Capabilities::accept_ssl_certs_>(
      kAcceptSslCertsKey);
  writer.TryWriteCapability<&Capabilities::native_events_>(kNativeEventsKey);

  return capabilities_value.PassAs<base::Value>();
}

base::optional<Capabilities> Capabilities::FromValue(const base::Value* value) {
  const base::DictionaryValue* value_as_dictionary;
  if (!value->GetAsDictionary(&value_as_dictionary)) {
    return base::nullopt;
  }
  // Create a new Capabilities object, and copy the capabilities dictionary
  // from which we will read capabilities
  Capabilities capabilities;
  scoped_ptr<base::DictionaryValue> capabilities_copy(
      value_as_dictionary->DeepCopy());

  // Read all the capabilities we know about, and remove handled capabilities
  // from the dictionary.
  CapabilityReader reader(&capabilities, capabilities_copy.get());
  reader.TryReadCapability<&Capabilities::browser_name_>(kBrowserNameKey);
  reader.TryReadCapability<&Capabilities::version_>(kVersionKey);
  reader.TryReadCapability<&Capabilities::platform_>(kPlatformKey);
  reader.TryReadCapability<&Capabilities::javascript_enabled_>(
      kJavascriptEnabledKey);
  reader.TryReadCapability<&Capabilities::takes_screenshot_>(
      kTakesScreenshotKey);
  reader.TryReadCapability<&Capabilities::handles_alerts_>(kHandlesAlertsKey);
  reader.TryReadCapability<&Capabilities::database_enabled_>(kDatabaseEnabled);
  reader.TryReadCapability<&Capabilities::location_context_enabled_>(
      kLocationContextEnabledKey);
  reader.TryReadCapability<&Capabilities::application_cache_enabled_>(
      kApplicationCacheEnabledKey);
  reader.TryReadCapability<&Capabilities::browser_connection_enabled_>(
      kBrowserConnectionEnabledKey);
  reader.TryReadCapability<&Capabilities::css_selectors_enabled_>(
      kCssSelectorsEnabledKey);
  reader.TryReadCapability<&Capabilities::web_storage_enabled_>(
      kWebStorageEnabledKey);
  reader.TryReadCapability<&Capabilities::rotatable_>(kRotatableKey);
  reader.TryReadCapability<&Capabilities::accept_ssl_certs_>(
      kAcceptSslCertsKey);
  reader.TryReadCapability<&Capabilities::native_events_>(kNativeEventsKey);

  reader.TryReadCapability<Proxy, &Capabilities::proxy_>(kProxyKey);
  return capabilities;
}

Capabilities Capabilities::CreateActualCapabilities() {
  Capabilities capabilities;
  // Set the capabilities that we know we support.
  capabilities.browser_name_ = "Cobalt";
  capabilities.version_ = COBALT_VERSION;
  // TODO: Support platforms other than Linux.
  capabilities.platform_ = "Linux";
  capabilities.javascript_enabled_ = true;
  capabilities.css_selectors_enabled_ = true;
  return capabilities;
}

bool Capabilities::AreCapabilitiesSupported() const {
  // TODO: Check for unsupported capabilities.
  return true;
}

base::optional<RequestedCapabilities> RequestedCapabilities::FromValue(
    const base::Value* value) {
  DCHECK(value);
  const base::DictionaryValue* requested_capabilities_value;
  if (!value->GetAsDictionary(&requested_capabilities_value)) {
    return base::nullopt;
  }

  base::optional<Capabilities> desired;
  const base::Value* capabilities_value = NULL;
  if (requested_capabilities_value->Get(kDesiredCapabilitiesKey,
                                        &capabilities_value)) {
    desired = Capabilities::FromValue(capabilities_value);
  }
  if (!desired) {
    // Desired capabilities are required.
    return base::nullopt;
  }
  base::optional<Capabilities> required;
  if (requested_capabilities_value->Get(kRequiredCapabilitiesKey,
                                        &capabilities_value)) {
    required = Capabilities::FromValue(capabilities_value);
  }
  if (required) {
    return RequestedCapabilities(desired.value(), required.value());
  } else {
    return RequestedCapabilities(desired.value());
  }
}

}  // namespace protocol
}  // namespace webdriver
}  // namespace cobalt
