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

#ifndef COBALT_WEBDRIVER_UTIL_DISPATCH_COMMAND_FACTORY_H_
#define COBALT_WEBDRIVER_UTIL_DISPATCH_COMMAND_FACTORY_H_

#include <algorithm>
#include <memory>
#include <string>
#include <vector>

#include "base/bind.h"
#include "base/callback.h"
#include "base/memory/ptr_util.h"

namespace cobalt {
namespace webdriver {
namespace util {
namespace internal {
namespace {
template <typename T>
struct ForwardType {
  typedef const T& value;
};

template <typename T>
struct ForwardType<T&> {
  typedef T& value;
};

template <typename T, size_t n>
struct ForwardType<T[n]> {
  typedef const T* value;
};

// See comment for CallbackParamTraits<T[n]>.
template <typename T>
struct ForwardType<T[]> {
  typedef const T* value;
};

// unique_ptr-like move-only types.
template <typename T>
struct ForwardType<std::unique_ptr<T>> {
  typedef std::unique_ptr<T> value;
};
}  // namespace

// Convert a value to a base::Value to return it as a part of the WebDriver
// response object.
template <typename T>
std::unique_ptr<base::Value> ToValue(const T& value) {
  return T::ToValue(value);
}

template <typename T>
std::unique_ptr<base::Value> ToValue(const std::vector<T>& value) {
  std::unique_ptr<base::ListValue> list_value(new base::ListValue());
  for (int i = 0; i < value.size(); ++i) {
    list_value->Append(std::move(ToValue<T>(value[i])));
  }
  return std::unique_ptr<base::Value>(list_value.release());
}

// Partial template specialization for base::optional.
template <typename T>
std::unique_ptr<base::Value> ToValue(const base::Optional<T>& value) {
  if (value) {
    return ToValue<T>(*value);
  } else {
    return std::make_unique<base::Value>();
  }
}

// Template specialization for std::string.
template <>
std::unique_ptr<base::Value> ToValue(const std::string& value) {
  return std::unique_ptr<base::Value>(new base::Value(value));
}

// Template specialization for bool.
template <>
std::unique_ptr<base::Value> ToValue(const bool& value) {
  return std::unique_ptr<base::Value>(new base::Value(value));
}

template <typename R>
std::unique_ptr<base::Value> ToValue(const CommandResult<R>& command_result) {
  return ToValue(command_result.result());
}

template <>
std::unique_ptr<base::Value> ToValue(
    const CommandResult<void>& command_result) {
  return std::make_unique<base::Value>();
}

// Convert a base::Value to a base::Optional<T>. If value could not be converted
// base::nullopt will be returned.
template <typename T>
base::Optional<T> FromValue(const base::Value* value) {
  return T::FromValue(value);
}

template <>
base::Optional<GURL> FromValue(const base::Value* value) {
  const char kUrlKey[] = "url";
  std::string url;
  const base::DictionaryValue* dictionary_value;
  if (!value->GetAsDictionary(&dictionary_value) ||
      !dictionary_value->GetString(kUrlKey, &url)) {
    return base::nullopt;
  }
  return GURL(url.c_str());
}

// Returns an appropriate response through the CommandResultHandler.
// On failure, the error response value is created and on success the
// result in the CommandResult instance is converted to a base::Value and
// returned.
template <typename R>
void ReturnResponse(const base::Optional<protocol::SessionId>& session_id,
                    const util::CommandResult<R>& command_result,
                    WebDriverDispatcher::CommandResultHandler* result_handler) {
  std::unique_ptr<base::Value> result;
  if (command_result.is_success()) {
    result = internal::ToValue(command_result);
  } else {
    result =
        protocol::Response::CreateErrorResponse(command_result.error_message());
  }
  result_handler->SendResult(session_id, command_result.status_code(),
                             std::move(result));
}

}  // namespace internal

// Helper class to create WebDriverDispatcher::DispatchCommandCallbacks that
// can be used with the WebDriverDispatcher::RegisterCommand function.
// Specify the XXXDriver class name as a template parameter.
template <class DriverClassT>
class DispatchCommandFactory
    : public base::RefCounted<DispatchCommandFactory<DriverClassT> > {
  // Max retries for the "can_retry" CommandResult case.
  static const int kMaxRetries = 5;

 public:
  // Typedef'd for less verbose code.
  typedef WebDriverDispatcher::CommandResultHandler CommandResultHandler;
  typedef WebDriverDispatcher::DispatchCommandCallback DispatchCommandCallback;
  typedef WebDriverDispatcher::PathVariableMap PathVariableMap;

  // Callback that takes PathVariableMap* and CommandResultHandler* as arguments
  // and returns a SessionDriver*.
  // Attempts to extract the sessionID from the PathVariableMap and finds the
  // session that this ID maps to. If no such session occurrs, an error is sent
  // through the CommandResultHandler and NULL is returned.
  typedef base::Callback<SessionDriver*(const PathVariableMap* path_variables,
                                        CommandResultHandler*)>
      GetSessionCommand;

  // Callback that takes PathVariableMap* and CommandResultHandler* as arguments
  // and returns a DriverClass*.
  // If necessary extracts the id from the PathVariableMap and finds the driver
  // that this ID maps to. If no such driver occurs, an error is sent through
  // the CommandResultHandler and NULL is returned.
  typedef base::Callback<DriverClassT*(SessionDriver*,
                                       const PathVariableMap* path_variables,
                                       CommandResultHandler*)> GetDriverCommand;

  // Takes GetSessionCommand and GetDriverCommand callbacks. These will be
  // called when the DispatchCommandCallback is called to try to find the
  // correct XXXDriver based on the path variables.
  DispatchCommandFactory(const GetSessionCommand& get_session,
                         const GetDriverCommand& get_driver)
      : get_session_(get_session), get_driver_(get_driver) {}

  // Returns a DispatchCommandCallback that will call the specified
  // command_callback.
  // If the path variables successfull map to a DriverClass instance, it will
  // be passed as the argument to the command_callback.
  // If no such DriverClass instance can be found, the command_callback will not
  // be run. The results of the command will be sent through the
  // CommandResultHandler.
  template <typename R>
  DispatchCommandCallback GetCommandHandler(
      const base::Callback<util::CommandResult<R>(DriverClassT*)>&
          command_callback) {
    typedef CommandHandler<R> CommandHandler;
    return CommandHandler::GetCommandHandler(
        get_session_, get_driver_,
        base::Bind(&CommandHandler::RunCommand, command_callback));
  }

  // Returns a DispatchCommandCallback that will call the specified
  // command_callback with an argument.
  // If the path variables successfull map to a DriverClass instance, it will
  // be passed as the argument to the command_callback.
  // If the parameters passed to the command cannot be converted to an instance
  // of type A1, the command_callback will not be called an an appropriate
  // error will be returned through the CommandRequestHandler.
  // If no such DriverClass instance can be found, the command_callback will not
  // be run.
  template <typename R, typename A1>
  DispatchCommandCallback GetCommandHandler(
      const base::Callback<util::CommandResult<R>(DriverClassT*, const A1&)>&
          command_callback) {
    typedef CommandHandler<R> CommandHandler;
    return CommandHandler::GetCommandHandler(
        get_session_, get_driver_,
        base::Bind(&CommandHandler::template ExtractParameterAndRunCommand<A1>,
                   command_callback));
  }

 private:
  // Works with the DispatchCommandFactory to create a DispatchCommandCallback
  // for a particular return value R. Putting this into a nested template class
  // helps alleviate some of the headaches of working with C++ templates.
  template <typename R>
  class CommandHandler : public base::RefCounted<CommandHandler<R> > {
   public:
    // Wrapper around an actual command to run. It will extract arguments from
    // |parameters| if necessary and pass them to the command.
    // If parameters cannot be extracted, an appropriate error will be sent to
    // the CommandResultHandler.
    // Upon successful completion of the command, the result will be sent to
    // CommandResultHandler.
    typedef base::Callback<void(
        const base::Optional<protocol::SessionId>&, DriverClassT* driver,
        const base::Value* parameters, CommandResultHandler* result_handler)>
        RunCommandCallback;

    typedef base::Callback<util::CommandResult<R>(DriverClassT*)>
        DriverCommandFunction;
    // After binding the first argument, this function signature matches that of
    // RunCommandCallback.
    // The first argument is a base::Callback that runs a DriverClassT member
    // function with no parameters.
    static void RunCommand(
        const DriverCommandFunction& driver_command,
        const base::Optional<protocol::SessionId>& session_id,
        DriverClassT* driver, const base::Value* parameters,
        CommandResultHandler* result_handler) {
      // Ignore parameters.
      int retries = 0;
      util::CommandResult<R> command_result;
      do {
        command_result = driver_command.Run(driver);
      } while (command_result.can_retry() && (retries++ < kMaxRetries));
      internal::ReturnResponse(session_id, command_result, result_handler);
    }

    // After binding the first argument, this function signature matches that of
    // RunCommandCallback.
    // The first argument is a base::Callback that runs a DriverClassT member
    // function with one parameter.
    template <typename A1>
    static void ExtractParameterAndRunCommand(
        const base::Callback<util::CommandResult<R>(
            DriverClassT*, typename internal::ForwardType<A1>::value)>&
            driver_command,
        const base::Optional<protocol::SessionId>& session_id,
        DriverClassT* driver, const base::Value* parameters,
        CommandResultHandler* result_handler) {
      // Extract the parameter from |parameters|. If unsuccessful, return a
      // kInvalidParameters error. Otherwise, pass the extracted parameter to
      // the |driver_command|.
      using A1_NO_REF = typename std::remove_reference<A1>::type;
      base::Optional<A1_NO_REF> param =
          internal::FromValue<A1_NO_REF>(parameters);
      if (!param) {
        result_handler->SendInvalidRequestResponse(
            WebDriverDispatcher::CommandResultHandler::kInvalidParameters, "");
      } else {
        int retries = 0;
        util::CommandResult<R> command_result;
        do {
          command_result = driver_command.Run(driver, param.value());
        } while (command_result.can_retry() && (retries++ < kMaxRetries));
        internal::ReturnResponse(session_id, command_result, result_handler);
      }
    }

    // Create a new CommandHandler instance, and base::Bind to its HandleCommand
    // function.
    static DispatchCommandCallback GetCommandHandler(
        const GetSessionCommand& get_session_command,
        const GetDriverCommand& get_driver_command,
        const RunCommandCallback& run_command_callback) {
      scoped_refptr<CommandHandler> command_handler(new CommandHandler(
          get_session_command, get_driver_command, run_command_callback));
      return base::Bind(&CommandHandler::HandleCommand, command_handler);
    }

   private:
    // Simple constructor that sets each of the necessary callbacks.
    CommandHandler(const GetSessionCommand& get_session_callback,
                   const GetDriverCommand& get_driver_callback,
                   const RunCommandCallback& run_command_callback)
        : get_session_(get_session_callback),
          get_driver_(get_driver_callback),
          run_command_(run_command_callback) {}

    // This function matches the WebDriverDispatcher::DispatchCommandCallback
    // signature, and as such is appropriate to be passed to the
    // WebDriverDispatcher::RegisterCommand function.
    // Using the the callbacks stored in this CommandHandler, it will extract
    // the appropriate XXXDriver, and execute |run_command_| on it.
    void HandleCommand(const base::Value* value,
                       const PathVariableMap* path_variables,
                       std::unique_ptr<CommandResultHandler> result_handler) {
      SessionDriver* session =
          get_session_.Run(path_variables, result_handler.get());
      if (session) {
        DriverClassT* driver =
            get_driver_.Run(session, path_variables, result_handler.get());
        if (driver) {
          run_command_.Run(session->session_id(), driver, value,
                           result_handler.get());
        }
      }
    }

    GetSessionCommand get_session_;
    GetDriverCommand get_driver_;
    RunCommandCallback run_command_;
  };

  GetSessionCommand get_session_;
  GetDriverCommand get_driver_;
};

}  // namespace util
}  // namespace webdriver
}  // namespace cobalt

#endif  // COBALT_WEBDRIVER_UTIL_DISPATCH_COMMAND_FACTORY_H_
