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

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/string_tokenizer.h"
#include "base/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(
      scoped_ptr<WebDriverServer::ResponseHandler> response_handler)
      : response_handler_(response_handler.Pass()) {}

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

  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:
  scoped_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;
  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,
    scoped_ptr<base::Value> request_value,
    scoped_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.
  scoped_ptr<CommandResultHandler> result_handler(
      new CommandResultHandlerImpl(response_handler.Pass()));
  command_it->second.Run(request_value.get(), &path_variable_map,
                         result_handler.Pass());
}

}  // namespace webdriver
}  // namespace cobalt
