// Copyright 2014 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "libweave/src/device_registration_info.h"

#include <base/json/json_reader.h>
#include <base/json/json_writer.h>
#include <base/values.h>
#include <chromeos/key_value_store.h>
#include <gtest/gtest.h>
#include <weave/mock_http_client.h>

#include "libweave/src/bind_lambda.h"
#include "libweave/src/commands/command_manager.h"
#include "libweave/src/commands/unittest_utils.h"
#include "libweave/src/http_constants.h"
#include "libweave/src/states/mock_state_change_queue_interface.h"
#include "libweave/src/states/state_manager.h"
#include "libweave/src/storage_impls.h"

using testing::_;
using testing::AtLeast;
using testing::Invoke;
using testing::InvokeWithoutArgs;
using testing::Mock;
using testing::Return;
using testing::ReturnRef;
using testing::ReturnRefOfCopy;
using testing::StrictMock;
using testing::WithArgs;

namespace weave {

using unittests::CreateDictionaryValue;
using unittests::CreateValue;
using unittests::MockHttpClient;
using unittests::MockHttpClientResponse;

namespace {

namespace test_data {

const char kServiceURL[] = "http://gcd.server.com/";
const char kOAuthURL[] = "http://oauth.server.com/";
const char kApiKey[] = "GOadRdTf9FERf0k4w6EFOof56fUJ3kFDdFL3d7f";
const char kClientId[] =
    "123543821385-sfjkjshdkjhfk234sdfsdfkskd"
    "fkjh7f.apps.googleusercontent.com";
const char kClientSecret[] = "5sdGdGlfolGlrFKfdFlgP6FG";
const char kDeviceId[] = "4a7ea2d1-b331-1e1f-b206-e863c7635196";
const char kClaimTicketId[] = "RTcUE";
const char kAccessToken[] =
    "ya29.1.AADtN_V-dLUM-sVZ0qVjG9Dxm5NgdS9J"
    "Mx_JLUqhC9bED_YFjzHZtYt65ZzXCS35NMAeaVZ"
    "Dei530-w0yE2urpQ";
const char kRefreshToken[] =
    "1/zQmxR6PKNvhcxf9SjXUrCjcmCrcqRKXctc6cp"
    "1nI-GQ";
const char kRobotAccountAuthCode[] =
    "4/Mf_ujEhPejVhOq-OxW9F5cSOnWzx."
    "YgciVjTYGscRshQV0ieZDAqiTIjMigI";
const char kRobotAccountEmail[] =
    "6ed0b3f54f9bd619b942f4ad2441c252@"
    "clouddevices.gserviceaccount.com";

}  // namespace test_data

// Add the test device registration information.
void SetDefaultDeviceRegistration(base::DictionaryValue* data) {
  data->SetString("refresh_token", test_data::kRefreshToken);
  data->SetString("device_id", test_data::kDeviceId);
  data->SetString("robot_account", test_data::kRobotAccountEmail);
}

std::string GetFormField(const std::string& data, const std::string& name) {
  EXPECT_FALSE(data.empty());
  for (const auto& i : WebParamsDecode(data)) {
    if (i.first == name)
      return i.second;
  }
  return {};
}

HttpClient::Response* ReplyWithJson(int status_code, const base::Value& json) {
  std::string text;
  base::JSONWriter::WriteWithOptions(
      json, base::JSONWriter::OPTIONS_PRETTY_PRINT, &text);

  MockHttpClientResponse* response = new StrictMock<MockHttpClientResponse>;
  EXPECT_CALL(*response, GetStatusCode())
      .Times(AtLeast(1))
      .WillRepeatedly(Return(status_code));
  EXPECT_CALL(*response, GetContentType())
      .Times(AtLeast(1))
      .WillRepeatedly(Return(http::kJsonUtf8));
  EXPECT_CALL(*response, GetData())
      .Times(AtLeast(1))
      .WillRepeatedly(ReturnRefOfCopy(text));
  return response;
}

std::pair<std::string, std::string> GetAuthHeader() {
  return {http::kAuthorization,
          std::string("Bearer ") + test_data::kAccessToken};
}

std::pair<std::string, std::string> GetJsonHeader() {
  return {http::kContentType, http::kJsonUtf8};
}

std::pair<std::string, std::string> GetFormHeader() {
  return {http::kContentType, http::kWwwFormUrlEncoded};
}

}  // anonymous namespace

class DeviceRegistrationInfoTest : public ::testing::Test {
 protected:
  void SetUp() override {
    EXPECT_CALL(mock_state_change_queue_, GetLastStateChangeId())
        .WillRepeatedly(Return(0));
    EXPECT_CALL(mock_state_change_queue_, MockAddOnStateUpdatedCallback(_))
        .WillRepeatedly(Return(nullptr));

    std::unique_ptr<StorageInterface> storage{new MemStorage};
    storage_ = storage.get();
    storage->Save(data_);
    command_manager_ = std::make_shared<CommandManager>();
    state_manager_ = std::make_shared<StateManager>(&mock_state_change_queue_);

    std::unique_ptr<BuffetConfig> config{new BuffetConfig{std::move(storage)}};
    config_ = config.get();
    dev_reg_.reset(new DeviceRegistrationInfo{command_manager_, state_manager_,
                                              std::move(config), nullptr,
                                              &http_client_, true, nullptr});

    ReloadConfig();
  }

  void ReloadConfig() {
    chromeos::KeyValueStore config_store;
    config_store.SetString("client_id", test_data::kClientId);
    config_store.SetString("client_secret", test_data::kClientSecret);
    config_store.SetString("api_key", test_data::kApiKey);
    config_store.SetString("device_kind", "vendor");
    config_store.SetString("name", "Coffee Pot");
    config_store.SetString("description", "Easy to clean");
    config_store.SetString("location", "Kitchen");
    config_store.SetString("local_anonymous_access_role", "viewer");
    config_store.SetString("model_id", "AAAAA");
    config_store.SetString("oauth_url", test_data::kOAuthURL);
    config_store.SetString("service_url", test_data::kServiceURL);
    config_->Load(config_store);
    dev_reg_->Start();
  }

  void PublishCommands(const base::ListValue& commands) {
    return dev_reg_->PublishCommands(commands);
  }

  bool RefreshAccessToken(chromeos::ErrorPtr* error) const {
    bool succeeded = false;
    auto on_success = [&succeeded]() { succeeded = true; };
    auto on_failure = [&error](const chromeos::Error* in_error) {
      if (error)
        *error = in_error->Clone();
    };
    dev_reg_->RefreshAccessToken(base::Bind(on_success),
                                 base::Bind(on_failure));
    return succeeded;
  }

  void SetAccessToken() { dev_reg_->access_token_ = test_data::kAccessToken; }

  RegistrationStatus GetRegistrationStatus() const {
    return dev_reg_->registration_status_;
  }

  StrictMock<MockHttpClient> http_client_;
  base::DictionaryValue data_;
  StorageInterface* storage_{nullptr};
  BuffetConfig* config_{nullptr};
  std::unique_ptr<DeviceRegistrationInfo> dev_reg_;
  std::shared_ptr<CommandManager> command_manager_;
  StrictMock<MockStateChangeQueueInterface> mock_state_change_queue_;
  std::shared_ptr<StateManager> state_manager_;
};

////////////////////////////////////////////////////////////////////////////////
TEST_F(DeviceRegistrationInfoTest, GetServiceURL) {
  EXPECT_EQ(test_data::kServiceURL, dev_reg_->GetServiceURL());
  std::string url = test_data::kServiceURL;
  url += "registrationTickets";
  EXPECT_EQ(url, dev_reg_->GetServiceURL("registrationTickets"));
  url += "?key=";
  url += test_data::kApiKey;
  EXPECT_EQ(url, dev_reg_->GetServiceURL("registrationTickets",
                                         {{"key", test_data::kApiKey}}));
  url += "&restart=true";
  EXPECT_EQ(url, dev_reg_->GetServiceURL(
                     "registrationTickets",
                     {
                         {"key", test_data::kApiKey}, {"restart", "true"},
                     }));
}

TEST_F(DeviceRegistrationInfoTest, GetOAuthURL) {
  EXPECT_EQ(test_data::kOAuthURL, dev_reg_->GetOAuthURL());
  std::string url = test_data::kOAuthURL;
  url += "auth?scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fclouddevices&";
  url += "redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&";
  url += "response_type=code&";
  url += "client_id=";
  url += test_data::kClientId;
  EXPECT_EQ(url, dev_reg_->GetOAuthURL(
                     "auth",
                     {{"scope", "https://www.googleapis.com/auth/clouddevices"},
                      {"redirect_uri", "urn:ietf:wg:oauth:2.0:oob"},
                      {"response_type", "code"},
                      {"client_id", test_data::kClientId}}));
}

TEST_F(DeviceRegistrationInfoTest, HaveRegistrationCredentials) {
  EXPECT_FALSE(dev_reg_->HaveRegistrationCredentials());
  SetDefaultDeviceRegistration(&data_);
  storage_->Save(data_);
  ReloadConfig();

  EXPECT_CALL(http_client_,
              MockSendRequest(http::kPost, dev_reg_->GetOAuthURL("token"),
                              HttpClient::Headers{GetFormHeader()}, _, _))
      .WillOnce(WithArgs<3>(Invoke([](const std::string& data) {
        EXPECT_EQ("refresh_token", GetFormField(data, "grant_type"));
        EXPECT_EQ(test_data::kRefreshToken,
                  GetFormField(data, "refresh_token"));
        EXPECT_EQ(test_data::kClientId, GetFormField(data, "client_id"));
        EXPECT_EQ(test_data::kClientSecret,
                  GetFormField(data, "client_secret"));

        base::DictionaryValue json;
        json.SetString("access_token", test_data::kAccessToken);
        json.SetInteger("expires_in", 3600);

        return ReplyWithJson(200, json);
      })));

  EXPECT_TRUE(RefreshAccessToken(nullptr));
  EXPECT_TRUE(dev_reg_->HaveRegistrationCredentials());
}

TEST_F(DeviceRegistrationInfoTest, CheckAuthenticationFailure) {
  SetDefaultDeviceRegistration(&data_);
  storage_->Save(data_);
  ReloadConfig();
  EXPECT_EQ(RegistrationStatus::kConnecting, GetRegistrationStatus());

  EXPECT_CALL(http_client_,
              MockSendRequest(http::kPost, dev_reg_->GetOAuthURL("token"),
                              HttpClient::Headers{GetFormHeader()}, _, _))
      .WillOnce(WithArgs<3>(Invoke([](const std::string& data) {
        EXPECT_EQ("refresh_token", GetFormField(data, "grant_type"));
        EXPECT_EQ(test_data::kRefreshToken,
                  GetFormField(data, "refresh_token"));
        EXPECT_EQ(test_data::kClientId, GetFormField(data, "client_id"));
        EXPECT_EQ(test_data::kClientSecret,
                  GetFormField(data, "client_secret"));

        base::DictionaryValue json;
        json.SetString("error", "unable_to_authenticate");
        return ReplyWithJson(400, json);
      })));

  chromeos::ErrorPtr error;
  EXPECT_FALSE(RefreshAccessToken(&error));
  EXPECT_TRUE(error->HasError(kErrorDomainOAuth2, "unable_to_authenticate"));
  EXPECT_EQ(RegistrationStatus::kConnecting, GetRegistrationStatus());
}

TEST_F(DeviceRegistrationInfoTest, CheckDeregistration) {
  SetDefaultDeviceRegistration(&data_);
  storage_->Save(data_);
  ReloadConfig();
  EXPECT_EQ(RegistrationStatus::kConnecting, GetRegistrationStatus());

  EXPECT_CALL(http_client_,
              MockSendRequest(http::kPost, dev_reg_->GetOAuthURL("token"),
                              HttpClient::Headers{GetFormHeader()}, _, _))
      .WillOnce(WithArgs<3>(Invoke([](const std::string& data) {
        EXPECT_EQ("refresh_token", GetFormField(data, "grant_type"));
        EXPECT_EQ(test_data::kRefreshToken,
                  GetFormField(data, "refresh_token"));
        EXPECT_EQ(test_data::kClientId, GetFormField(data, "client_id"));
        EXPECT_EQ(test_data::kClientSecret,
                  GetFormField(data, "client_secret"));

        base::DictionaryValue json;
        json.SetString("error", "invalid_grant");
        return ReplyWithJson(400, json);
      })));

  chromeos::ErrorPtr error;
  EXPECT_FALSE(RefreshAccessToken(&error));
  EXPECT_TRUE(error->HasError(kErrorDomainOAuth2, "invalid_grant"));
  EXPECT_EQ(RegistrationStatus::kInvalidCredentials, GetRegistrationStatus());
}

TEST_F(DeviceRegistrationInfoTest, GetDeviceInfo) {
  SetDefaultDeviceRegistration(&data_);
  storage_->Save(data_);
  ReloadConfig();
  SetAccessToken();

  EXPECT_CALL(http_client_,
              MockSendRequest(
                  http::kGet, dev_reg_->GetDeviceURL(),
                  HttpClient::Headers{GetAuthHeader(), GetJsonHeader()}, _, _))
      .WillOnce(WithArgs<3>(Invoke([](const std::string& data) {
        base::DictionaryValue json;
        json.SetString("channel.supportedType", "xmpp");
        json.SetString("deviceKind", "vendor");
        json.SetString("id", test_data::kDeviceId);
        json.SetString("kind", "clouddevices#device");
        return ReplyWithJson(200, json);
      })));

  bool succeeded = false;
  auto on_success = [&succeeded, this](const base::DictionaryValue& info) {
    std::string id;
    EXPECT_TRUE(info.GetString("id", &id));
    EXPECT_EQ(test_data::kDeviceId, id);
    succeeded = true;
  };
  auto on_failure = [](const chromeos::Error* error) {
    FAIL() << "Should not be called";
  };
  dev_reg_->GetDeviceInfo(base::Bind(on_success), base::Bind(on_failure));
  EXPECT_TRUE(succeeded);
}

TEST_F(DeviceRegistrationInfoTest, RegisterDevice) {
  auto json_base = CreateDictionaryValue(R"({
    'base': {
      'reboot': {
        'parameters': {'delay': 'integer'},
        'minimalRole': 'user',
        'results': {}
      },
      'shutdown': {
        'parameters': {},
        'minimalRole': 'user',
        'results': {}
      }
    }
  })");
  EXPECT_TRUE(command_manager_->LoadBaseCommands(*json_base, nullptr));
  auto json_cmds = CreateDictionaryValue(R"({
    'base': {
      'reboot': {
        'parameters': {'delay': {'minimum': 10}},
        'minimalRole': 'user',
        'results': {}
      }
    },
    'robot': {
      '_jump': {
        'parameters': {'_height': 'integer'},
        'minimalRole': 'user',
        'results': {}
      }
    }
  })");
  EXPECT_TRUE(command_manager_->LoadCommands(*json_cmds, "", nullptr));

  std::string ticket_url = dev_reg_->GetServiceURL("registrationTickets/") +
                           test_data::kClaimTicketId;
  EXPECT_CALL(
      http_client_,
      MockSendRequest(http::kPatch, ticket_url + "?key=" + test_data::kApiKey,
                      HttpClient::Headers{GetJsonHeader()}, _, _))
      .WillOnce(WithArgs<3>(Invoke([](const std::string& data) {
        auto json = unittests::CreateDictionaryValue(data);
        EXPECT_NE(nullptr, json.get());
        std::string value;
        EXPECT_TRUE(json->GetString("id", &value));
        EXPECT_EQ(test_data::kClaimTicketId, value);
        EXPECT_TRUE(
            json->GetString("deviceDraft.channel.supportedType", &value));
        EXPECT_EQ("pull", value);
        EXPECT_TRUE(json->GetString("oauthClientId", &value));
        EXPECT_EQ(test_data::kClientId, value);
        EXPECT_TRUE(json->GetString("deviceDraft.deviceKind", &value));
        EXPECT_EQ("vendor", value);
        EXPECT_TRUE(json->GetString("deviceDraft.description", &value));
        EXPECT_EQ("Easy to clean", value);
        EXPECT_TRUE(json->GetString("deviceDraft.location", &value));
        EXPECT_EQ("Kitchen", value);
        EXPECT_TRUE(json->GetString("deviceDraft.modelManifestId", &value));
        EXPECT_EQ("AAAAA", value);
        EXPECT_TRUE(json->GetString("deviceDraft.name", &value));
        EXPECT_EQ("Coffee Pot", value);
        base::DictionaryValue* commandDefs = nullptr;
        EXPECT_TRUE(
            json->GetDictionary("deviceDraft.commandDefs", &commandDefs));
        EXPECT_FALSE(commandDefs->empty());

        auto expected = R"({
            'base': {
              'reboot': {
                'parameters': {
                  'delay': {
                    'minimum': 10,
                    'type': 'integer'
                  }
                },
                'minimalRole': 'user'
              }
            },
            'robot': {
              '_jump': {
                'parameters': {
                  '_height': {
                    'type': 'integer'
                  }
                },
                'minimalRole': 'user'
              }
            }
          })";
        EXPECT_JSON_EQ(expected, *commandDefs);

        base::DictionaryValue json_resp;
        json_resp.SetString("id", test_data::kClaimTicketId);
        json_resp.SetString("kind", "clouddevices#registrationTicket");
        json_resp.SetString("oauthClientId", test_data::kClientId);
        base::DictionaryValue* device_draft = nullptr;
        EXPECT_TRUE(json->GetDictionary("deviceDraft", &device_draft));
        device_draft = device_draft->DeepCopy();
        device_draft->SetString("id", test_data::kDeviceId);
        device_draft->SetString("kind", "clouddevices#device");
        json_resp.Set("deviceDraft", device_draft);

        return ReplyWithJson(200, json_resp);
      })));

  EXPECT_CALL(http_client_,
              MockSendRequest(http::kPost, ticket_url + "/finalize?key=" +
                                               test_data::kApiKey,
                              HttpClient::Headers{}, _, _))
      .WillOnce(InvokeWithoutArgs([]() {
        base::DictionaryValue json;
        json.SetString("id", test_data::kClaimTicketId);
        json.SetString("kind", "clouddevices#registrationTicket");
        json.SetString("oauthClientId", test_data::kClientId);
        json.SetString("userEmail", "user@email.com");
        json.SetString("deviceDraft.id", test_data::kDeviceId);
        json.SetString("deviceDraft.kind", "clouddevices#device");
        json.SetString("deviceDraft.channel.supportedType", "xmpp");
        json.SetString("robotAccountEmail", test_data::kRobotAccountEmail);
        json.SetString("robotAccountAuthorizationCode",
                       test_data::kRobotAccountAuthCode);
        return ReplyWithJson(200, json);
      }));

  EXPECT_CALL(http_client_,
              MockSendRequest(http::kPost, dev_reg_->GetOAuthURL("token"),
                              HttpClient::Headers{GetFormHeader()}, _, _))
      .WillOnce(WithArgs<3>(Invoke([](const std::string& data) {
        EXPECT_EQ("authorization_code", GetFormField(data, "grant_type"));
        EXPECT_EQ(test_data::kRobotAccountAuthCode, GetFormField(data, "code"));
        EXPECT_EQ(test_data::kClientId, GetFormField(data, "client_id"));
        EXPECT_EQ(test_data::kClientSecret,
                  GetFormField(data, "client_secret"));

        EXPECT_EQ("oob", GetFormField(data, "redirect_uri"));
        EXPECT_EQ("https://www.googleapis.com/auth/clouddevices",
                  GetFormField(data, "scope"));

        base::DictionaryValue json;
        json.SetString("access_token", test_data::kAccessToken);
        json.SetString("token_type", "Bearer");
        json.SetString("refresh_token", test_data::kRefreshToken);
        json.SetInteger("expires_in", 3600);

        return ReplyWithJson(200, json);
      })));

  std::string device_id =
      dev_reg_->RegisterDevice(test_data::kClaimTicketId, nullptr);

  EXPECT_EQ(test_data::kDeviceId, device_id);
  EXPECT_EQ(RegistrationStatus::kConnecting, GetRegistrationStatus());

  // Validate the device info saved to storage...
  auto storage_data = storage_->Load();
  base::DictionaryValue* dict = nullptr;
  EXPECT_TRUE(storage_data->GetAsDictionary(&dict));
  std::string value;
  EXPECT_TRUE(dict->GetString("device_id", &value));
  EXPECT_EQ(test_data::kDeviceId, value);
  EXPECT_TRUE(dict->GetString("refresh_token", &value));
  EXPECT_EQ(test_data::kRefreshToken, value);
  EXPECT_TRUE(dict->GetString("robot_account", &value));
  EXPECT_EQ(test_data::kRobotAccountEmail, value);
}

TEST_F(DeviceRegistrationInfoTest, OOBRegistrationStatus) {
  // After we've been initialized, we should be either offline or
  // unregistered, depending on whether or not we've found credentials.
  EXPECT_EQ(RegistrationStatus::kUnconfigured, GetRegistrationStatus());
  // Put some credentials into our state, make sure we call that offline.
  SetDefaultDeviceRegistration(&data_);
  storage_->Save(data_);
  ReloadConfig();
  EXPECT_EQ(RegistrationStatus::kConnecting, GetRegistrationStatus());
}

TEST_F(DeviceRegistrationInfoTest, UpdateCommand) {
  SetDefaultDeviceRegistration(&data_);
  storage_->Save(data_);
  ReloadConfig();
  SetAccessToken();

  auto json_cmds = CreateDictionaryValue(R"({
    'robot': {
      '_jump': {
        'parameters': {'_height': 'integer'},
        'progress': {'progress': 'integer'},
        'results': {'status': 'string'},
        'minimalRole': 'user'
      }
    }
  })");
  EXPECT_TRUE(command_manager_->LoadCommands(*json_cmds, "", nullptr));

  const std::string command_url = dev_reg_->GetServiceURL("commands/1234");

  auto commands_json = CreateValue(R"([{
    'name':'robot._jump',
    'id':'1234',
    'parameters': {'_height': 100},
    'minimalRole': 'user'
  }])");
  ASSERT_NE(nullptr, commands_json.get());
  const base::ListValue* command_list = nullptr;
  ASSERT_TRUE(commands_json->GetAsList(&command_list));
  PublishCommands(*command_list);
  auto command = command_manager_->FindCommand("1234");
  ASSERT_NE(nullptr, command);

  EXPECT_CALL(http_client_,
              MockSendRequest(
                  http::kPatch, command_url,
                  HttpClient::Headers{GetAuthHeader(), GetJsonHeader()}, _, _))
      .WillOnce(WithArgs<3>(Invoke([](const std::string& data) {
        EXPECT_JSON_EQ(R"({"results":{"status":"Ok"}})",
                       *CreateDictionaryValue(data));
        base::DictionaryValue json;
        return ReplyWithJson(200, json);
      })));
  EXPECT_TRUE(
      command->SetResults(*CreateDictionaryValue("{'status': 'Ok'}"), nullptr));
  Mock::VerifyAndClearExpectations(&http_client_);

  EXPECT_CALL(http_client_,
              MockSendRequest(
                  http::kPatch, command_url,
                  HttpClient::Headers{GetAuthHeader(), GetJsonHeader()}, _, _))
      .WillOnce(WithArgs<3>(Invoke([](const std::string& data) {
        EXPECT_JSON_EQ(R"({"state":"inProgress"})",
                       *CreateDictionaryValue(data));
        base::DictionaryValue json;
        return ReplyWithJson(200, json);
      })))
      .WillOnce(WithArgs<3>(Invoke([](const std::string& data) {
        EXPECT_JSON_EQ(R"({"progress":{"progress":18}})",
                       *CreateDictionaryValue(data));
        base::DictionaryValue json;
        return ReplyWithJson(200, json);
      })));
  EXPECT_TRUE(
      command->SetProgress(*CreateDictionaryValue("{'progress':18}"), nullptr));
  Mock::VerifyAndClearExpectations(&http_client_);

  EXPECT_CALL(http_client_,
              MockSendRequest(
                  http::kPatch, command_url,
                  HttpClient::Headers{GetAuthHeader(), GetJsonHeader()}, _, _))
      .WillOnce(WithArgs<3>(Invoke([](const std::string& data) {
        EXPECT_JSON_EQ(R"({"state":"cancelled"})",
                       *CreateDictionaryValue(data));
        base::DictionaryValue json;
        return ReplyWithJson(200, json);
      })));
  command->Cancel();
  Mock::VerifyAndClearExpectations(&http_client_);
}

}  // namespace weave
