/*
 * 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
