// Copyright 2015 The Cobalt Authors. 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/dispatcher.h"

#include <algorithm>
#include <memory>
#include <utility>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/strings/string_tokenizer.h"
#include "base/strings/string_util.h"
#include "cobalt/webdriver/protocol/response.h"

namespace cobalt {
namespace webdriver {
namespace {

const char kVariablePrefix = ':';

// CommandResultHandler implementation that sends the results of a
// WebDriver command to a WebDriverServer::ResponseHandler.
class CommandResultHandlerImpl
    : public WebDriverDispatcher::CommandResultHandler {
 public:
  CommandResultHandlerImpl(
      std::unique_ptr<WebDriverServer::ResponseHandler> response_handler)
      : response_handler_(std::move(response_handler)) {}

  void SendResult(
      const base::Optional<protocol::SessionId>& session_id,
      protocol::Response::StatusCode status_code,
      std::unique_ptr<base::Value> webdriver_response_value) override {
    std::unique_ptr<base::Value> response = protocol::Response::CreateResponse(
        session_id, status_code, std::move(webdriver_response_value));
    if (status_code == protocol::Response::kSuccess) {
      response_handler_->Success(std::move(response));
    } else {
      response_handler_->FailedCommand(std::move(response));
    }
  }

  void SendResultWithContentType(protocol::Response::StatusCode status_code,
                                 const std::string& content_type,
                                 const char* data, int len) override {
    if (status_code == protocol::Response::kSuccess) {
      response_handler_->SuccessData(content_type, data, len);
    } else {
      std::unique_ptr<base::Value> response =
          protocol::Response::CreateResponse(base::nullopt, status_code, NULL);
      response_handler_->FailedCommand(std::move(response));
    }
  }

  void SendInvalidRequestResponse(RequestError error,
                                  const std::string& error_string) override {
    switch (error) {
      case kInvalidParameters:
        response_handler_->MissingCommandParameters(error_string);
        break;
      case kInvalidPathVariable:
        response_handler_->VariableResourceNotFound(error_string);
        break;
    }
  }

 private:
  std::unique_ptr<WebDriverServer::ResponseHandler> response_handler_;
};

// Helper function to get all supported methods for a given mapping of
// HttpMethod to DispatchCommandCallback.
typedef base::hash_map<WebDriverServer::HttpMethod,
                       WebDriverDispatcher::DispatchCommandCallback>
    MethodToCommandMap;
std::vector<WebDriverServer::HttpMethod> GetAvailableMethods(
    const MethodToCommandMap& method_lookup) {
  std::vector<WebDriverServer::HttpMethod> available_methods;
  for (MethodToCommandMap::const_iterator it = method_lookup.begin();
       it != method_lookup.end(); ++it) {
    available_methods.push_back(it->first);
  }
  return available_methods;
}

// Populate a PathVariableMapInternal mapping based on the components of a
// registered URL and a requested path.
// The key of the map will be the name of the variable component, and the value
// will be the actual value of the corresponding component in the request.
typedef base::hash_map<std::string, std::string> PathVariableMapInternal;
void PopulatePathVariableMap(PathVariableMapInternal* path_variable_map,
                             const std::vector<std::string>& request,
                             const std::vector<std::string>& path_components) {
  DCHECK_EQ(path_components.size(), request.size());
  for (size_t i = 0; i < request.size(); ++i) {
    DCHECK(!path_components[i].empty());
    // If the path component starts with a colon, it is a variable. Map the
    // variable name (dropping the colon) to the actual value in the request.
    if (path_components[i][0] == kVariablePrefix) {
      (*path_variable_map)[path_components[i]] = request[i];
    }
  }
}

// Tokenize a URL path by component.
std::vector<std::string> TokenizePath(const std::string& path) {
  std::vector<std::string> tokenized_path;
  base::StringTokenizer tokenizer(path, "/");
  while (tokenizer.GetNext()) {
    tokenized_path.push_back(tokenizer.token());
  }
  return tokenized_path;
}

// Used to compare two path components. If match_exact is set to false,
// then if either path is a variable component (starts with ':'), they will
// trivially match.
class PathComponentsAreEqualPredicate {
 public:
  explicit PathComponentsAreEqualPredicate(bool match_exact)
      : match_exact_(match_exact) {}

  bool operator()(const std::string& lhs, const std::string& rhs) const {
    if (!match_exact_ && (StartsWithColon(lhs) || StartsWithColon(rhs))) {
      return true;
    }
    return lhs == rhs;
  }

 private:
  bool StartsWithColon(const std::string& s) const {
    return !s.empty() && s[0] == kVariablePrefix;
  }
  bool match_exact_;
};

}  // namespace

void WebDriverDispatcher::RegisterCommand(
    WebDriverServer::HttpMethod method, const std::string& path,
    const DispatchCommandCallback& callback) {
  // Break the registered path into components.
  std::vector<std::string> tokenized_path = TokenizePath(path);
  // Find the registered CommandMapping struct if any other methods have been
  // registered for this path yet. Use exact matching so that we don't match
  // any path variables as wildcards.
  CommandMapping* mapping = GetMappingForPath(tokenized_path, kMatchExact);
  if (!mapping) {
    // No commands registered for this path yet, so create a new CommandMapping.
    int tokenized_path_size = static_cast<int>(tokenized_path.size());
    CommandMappingLookup::iterator it = command_lookup_.insert(
        std::make_pair(tokenized_path_size, CommandMapping(tokenized_path)));
    mapping = &it->second;
  }

  // Register this Http method for this CommandMapping.
  CommandMapping::MethodToCommandMap& method_to_command_map =
      mapping->command_map;
  DCHECK(method_to_command_map.end() == method_to_command_map.find(method));
  method_to_command_map[method] = callback;
}

WebDriverDispatcher::CommandMapping* WebDriverDispatcher::GetMappingForPath(
    const std::vector<std::string>& components, MatchStrategy strategy) {
  // Use reverse iterators for the match so we can early-out of a mismatch
  // more quickly. Most requests start with '/session/:sessionId/', for
  // example.
  typedef std::vector<std::string>::const_reverse_iterator MismatchResult;
  typedef std::pair<MismatchResult, MismatchResult> MismatchResultPair;
  typedef std::pair<CommandMappingLookup::iterator,
                    CommandMappingLookup::iterator> EqualRangeResultPair;

  PathComponentsAreEqualPredicate predicate(strategy == kMatchExact);

  // First find all commands that have the same number of components.
  EqualRangeResultPair pair_range =
      command_lookup_.equal_range(components.size());

  // For each command mapping that has the correct number of components,
  // check if the components match the CommandMapping's components.
  for (CommandMappingLookup::iterator it = pair_range.first;
       it != pair_range.second; ++it) {
    DCHECK_EQ(components.size(), it->second.path_components.size());
    // mismatch will return a pair of iterators to the first item in each
    // sequence that is not equal.
    MismatchResultPair result_pair =
        std::mismatch(components.rbegin(), components.rend(),
                      it->second.path_components.rbegin(), predicate);
    if (result_pair.first == components.rend()) {
      DCHECK(result_pair.second ==
             static_cast<MismatchResult>(it->second.path_components.rend()));
      return &it->second;
    }
  }
  return NULL;
}

void WebDriverDispatcher::HandleWebDriverServerRequest(
    WebDriverServer::HttpMethod method, const std::string& path,
    std::unique_ptr<base::Value> request_value,
    std::unique_ptr<WebDriverServer::ResponseHandler> response_handler) {
  // Tokenize the requested resource path and look up a CommandMapping for it,
  // matching variables.
  std::vector<std::string> tokenized_request = TokenizePath(path);
  const CommandMapping* command_mapping =
      GetMappingForPath(tokenized_request, kMatchVariables);

  if (command_mapping == NULL) {
    // No commands were registered to this path.
    response_handler->UnknownCommand(path);
    return;
  }

  CommandMapping::MethodToCommandMap::const_iterator command_it =
      command_mapping->command_map.find(method);
  if (command_it == command_mapping->command_map.end()) {
    // The requested URL maps to a known command, but not with the requested
    // method.
    response_handler->InvalidCommandMethod(
        method, GetAvailableMethods(command_mapping->command_map));
    return;
  }

  // Convert any variable components of the path to a mapping.
  PathVariableMapInternal path_variables;
  PopulatePathVariableMap(&path_variables, tokenized_request,
                          command_mapping->path_components);
  PathVariableMap path_variable_map(path_variables);

  // Create a new CommandResultHandler that will be passed to the Command
  // callback, and run the callback.
  std::unique_ptr<CommandResultHandler> result_handler(
      new CommandResultHandlerImpl(std::move(response_handler)));
  command_it->second.Run(request_value.get(), &path_variable_map,
                         std::move(result_handler));
}

}  // namespace webdriver
}  // namespace cobalt
