// Copyright 2015 The Weave 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 "src/device_registration_info.h"

#include <base/json/json_reader.h>
#include <base/json/json_writer.h>
#include <base/values.h>
#include <gtest/gtest.h>
#include <weave/provider/test/fake_task_runner.h>
#include <weave/provider/test/mock_config_store.h>
#include <weave/provider/test/mock_http_client.h>
#include <weave/test/unittest_utils.h>

#include "src/bind_lambda.h"
#include "src/component_manager_impl.h"
#include "src/http_constants.h"
#include "src/privet/auth_manager.h"
#include "src/test/mock_clock.h"

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

namespace weave {

using test::CreateDictionaryValue;
using test::CreateValue;
using provider::test::MockHttpClient;
using provider::test::MockHttpClientResponse;
using provider::HttpClient;

namespace {

namespace test_data {

const char kXmppEndpoint[] = "xmpp.server.com:1234";
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 kCloudId[] = "4a7ea2d1-b331-1e1f-b206-e863c7635196";
const char kDeviceId[] = "f6885e46-b432-42d7-86a5-d759bfb61f62";
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";
const char kAuthInfo[] = R"({
  "localAuthInfo": {
    "certFingerprint":
    "FQY6BEINDjw3FgsmYChRWgMzMhc4TC8uG0UUUFhdDz0=",
    "localId": "f6885e46-b432-42d7-86a5-d759bfb61f62"
  }
})";

}  // namespace test_data

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 {};
}

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

  std::unique_ptr<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(Return(text));
  return std::move(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(clock_, Now())
        .WillRepeatedly(Return(base::Time::FromTimeT(1450000000)));
    ReloadDefaults(true);
  }

  void ReloadDefaults(bool allow_endpoints_override) {
    EXPECT_CALL(config_store_, LoadDefaults(_))
        .WillOnce(Invoke([allow_endpoints_override](Settings* settings) {
          settings->client_id = test_data::kClientId;
          settings->client_secret = test_data::kClientSecret;
          settings->api_key = test_data::kApiKey;
          settings->oem_name = "Coffee Pot Maker";
          settings->model_name = "Pot v1";
          settings->name = "Coffee Pot";
          settings->description = "Easy to clean";
          settings->location = "Kitchen";
          settings->local_anonymous_access_role = AuthScope::kViewer;
          settings->model_id = "AAAAA";
          settings->oauth_url = test_data::kOAuthUrl;
          settings->service_url = test_data::kServiceUrl;
          settings->xmpp_endpoint = test_data::kXmppEndpoint;
          settings->allow_endpoints_override = allow_endpoints_override;
          return true;
        }));
    config_.reset(new Config{&config_store_});
    dev_reg_.reset(new DeviceRegistrationInfo{
        config_.get(), &component_manager_, &task_runner_, &http_client_,
        nullptr, &auth_});
    dev_reg_->Start();
  }

  void ReloadSettings(bool registered, bool allow_endpoints_override) {
    base::DictionaryValue dict;
    dict.SetInteger("version", 1);
    if (registered) {
      dict.SetString("refresh_token", test_data::kRefreshToken);
      dict.SetString("cloud_id", test_data::kCloudId);
      dict.SetString("robot_account", test_data::kRobotAccountEmail);
    }
    dict.SetString("device_id", test_data::kDeviceId);
    std::string json_string;
    base::JSONWriter::WriteWithOptions(
        dict, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json_string);
    EXPECT_CALL(config_store_, LoadSettings()).WillOnce(Return(json_string));
    ReloadDefaults(allow_endpoints_override);
  }

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

  bool RefreshAccessToken(ErrorPtr* error) const {
    bool succeeded = false;
    auto callback = [&succeeded, &error](ErrorPtr in_error) {
      if (error) {
        *error = std::move(in_error);
        return;
      }
      succeeded = true;
    };
    dev_reg_->RefreshAccessToken(base::Bind(callback));
    return succeeded;
  }

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

  GcdState GetGcdState() const { return dev_reg_->GetGcdState(); }

  bool HaveRegistrationCredentials() const {
    return dev_reg_->HaveRegistrationCredentials();
  }

  void RegisterDevice(const RegistrationData registration_data,
                      const RegistrationData& expected_data);

  provider::test::FakeTaskRunner task_runner_;
  provider::test::MockConfigStore config_store_;
  StrictMock<MockHttpClient> http_client_;
  base::DictionaryValue data_;
  std::unique_ptr<Config> config_;
  test::MockClock clock_;
  privet::AuthManager auth_{
      {68, 52, 36, 95, 74, 89, 25, 2, 31, 5, 65, 87, 64, 32, 17, 26, 8, 73, 57,
       16, 33, 82, 71, 10, 72, 62, 45, 1, 77, 97, 70, 24},
      {21, 6, 58, 4, 66, 13, 14, 60, 55, 22, 11, 38, 96, 40, 81, 90, 3, 51, 50,
       23, 56, 76, 47, 46, 27, 69, 20, 80, 88, 93, 15, 61},
      {},
      &clock_};
  std::unique_ptr<DeviceRegistrationInfo> dev_reg_;
  ComponentManagerImpl component_manager_{&task_runner_};
};

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?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", {{"redirect_uri", "urn:ietf:wg:oauth:2.0:oob"},
                              {"response_type", "code"},
                              {"client_id", test_data::kClientId}}));
}

TEST_F(DeviceRegistrationInfoTest, HaveRegistrationCredentials) {
  EXPECT_FALSE(HaveRegistrationCredentials());
  ReloadSettings(true, false);

  EXPECT_CALL(
      http_client_,
      SendRequest(HttpClient::Method::kPost, dev_reg_->GetOAuthUrl("token"),
                  HttpClient::Headers{GetFormHeader()}, _, _))
      .WillOnce(WithArgs<3, 4>(
          Invoke([](const std::string& data,
                    const HttpClient::SendRequestCallback& callback) {
            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);

            callback.Run(ReplyWithJson(200, json), nullptr);
          })));

  EXPECT_CALL(
      http_client_,
      SendRequest(HttpClient::Method::kPost, HasSubstr("upsertLocalAuthInfo"),
                  HttpClient::Headers{GetAuthHeader(), GetJsonHeader()}, _, _))
      .WillOnce(WithArgs<3, 4>(
          Invoke([](const std::string& data,
                    const HttpClient::SendRequestCallback& callback) {
            auto dict = CreateDictionaryValue(data);
            EXPECT_TRUE(dict->Remove("localAuthInfo.clientToken", nullptr));
            EXPECT_JSON_EQ(test_data::kAuthInfo, *dict);
            base::DictionaryValue json;
            callback.Run(ReplyWithJson(200, json), nullptr);
          })));

  EXPECT_TRUE(RefreshAccessToken(nullptr));
  EXPECT_TRUE(HaveRegistrationCredentials());
}

TEST_F(DeviceRegistrationInfoTest, CheckAuthenticationFailure) {
  ReloadSettings(true, false);
  EXPECT_EQ(GcdState::kConnecting, GetGcdState());

  EXPECT_CALL(
      http_client_,
      SendRequest(HttpClient::Method::kPost, dev_reg_->GetOAuthUrl("token"),
                  HttpClient::Headers{GetFormHeader()}, _, _))
      .WillOnce(WithArgs<3, 4>(
          Invoke([](const std::string& data,
                    const HttpClient::SendRequestCallback& callback) {
            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");
            callback.Run(ReplyWithJson(400, json), nullptr);
          })));

  ErrorPtr error;
  EXPECT_FALSE(RefreshAccessToken(&error));
  EXPECT_TRUE(error->HasError("unable_to_authenticate"));
  EXPECT_EQ(GcdState::kConnecting, GetGcdState());
}

TEST_F(DeviceRegistrationInfoTest, CheckDeregistration) {
  ReloadSettings(true, false);
  EXPECT_EQ(GcdState::kConnecting, GetGcdState());

  EXPECT_CALL(
      http_client_,
      SendRequest(HttpClient::Method::kPost, dev_reg_->GetOAuthUrl("token"),
                  HttpClient::Headers{GetFormHeader()}, _, _))
      .WillOnce(WithArgs<3, 4>(
          Invoke([](const std::string& data,
                    const HttpClient::SendRequestCallback& callback) {
            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");
            callback.Run(ReplyWithJson(400, json), nullptr);
          })));

  ErrorPtr error;
  EXPECT_FALSE(RefreshAccessToken(&error));
  EXPECT_TRUE(error->HasError("invalid_grant"));
  EXPECT_EQ(GcdState::kInvalidCredentials, GetGcdState());
  EXPECT_EQ(test_data::kCloudId, dev_reg_->GetSettings().cloud_id);
}

TEST_F(DeviceRegistrationInfoTest, GetDeviceInfo) {
  ReloadSettings(true, false);
  SetAccessToken();

  EXPECT_CALL(
      http_client_,
      SendRequest(HttpClient::Method::kGet, dev_reg_->GetDeviceUrl(),
                  HttpClient::Headers{GetAuthHeader(), GetJsonHeader()}, _, _))
      .WillOnce(WithArgs<3, 4>(
          Invoke([](const std::string& data,
                    const HttpClient::SendRequestCallback& callback) {
            base::DictionaryValue json;
            json.SetString("channel.supportedType", "xmpp");
            json.SetString("deviceKind", "vendor");
            json.SetString("id", test_data::kCloudId);
            json.SetString("kind", "weave#device");
            callback.Run(ReplyWithJson(200, json), nullptr);
          })));

  bool succeeded = false;
  auto callback = [&succeeded, this](const base::DictionaryValue& info,
                                     ErrorPtr error) {
    EXPECT_FALSE(error);
    std::string id;
    EXPECT_TRUE(info.GetString("id", &id));
    EXPECT_EQ(test_data::kCloudId, id);
    succeeded = true;
  };
  dev_reg_->GetDeviceInfo(base::Bind(callback));
  EXPECT_TRUE(succeeded);
}

TEST_F(DeviceRegistrationInfoTest, ReRegisterDevice) {
  ReloadSettings(true, false);

  bool done = false;
  dev_reg_->RegisterDevice(RegistrationData{test_data::kClaimTicketId},
                           base::Bind([this, &done](ErrorPtr error) {
                             EXPECT_TRUE(error->HasError("already_registered"));
                             done = true;
                             task_runner_.Break();
                             EXPECT_EQ(GcdState::kConnecting, GetGcdState());

                             // Validate the device info saved to storage...
                             EXPECT_EQ(test_data::kCloudId,
                                       dev_reg_->GetSettings().cloud_id);
                             EXPECT_EQ(test_data::kRefreshToken,
                                       dev_reg_->GetSettings().refresh_token);
                             EXPECT_EQ(test_data::kRobotAccountEmail,
                                       dev_reg_->GetSettings().robot_account);
                           }));
  task_runner_.Run();
  EXPECT_TRUE(done);
}

void DeviceRegistrationInfoTest::RegisterDevice(
    const RegistrationData registration_data,
    const RegistrationData& expected_data) {
  auto json_traits = CreateDictionaryValue(R"({
    'base': {
      'commands': {
        'reboot': {
          'parameters': {'delay': {'minimum': 10, 'type': 'integer'}},
          'minimalRole': 'user'
        }
      },
      'state': {
        'firmwareVersion': {'type': 'string'}
      }
    },
    'robot': {
      'commands': {
        '_jump': {
          'parameters': {'_height': {'type': 'integer'}},
          'minimalRole': 'user'
        }
      }
    }
  })");
  EXPECT_TRUE(component_manager_.LoadTraits(*json_traits, nullptr));
  EXPECT_TRUE(
      component_manager_.AddComponent("", "comp", {"base", "robot"}, nullptr));
  base::StringValue ver{"1.0"};
  EXPECT_TRUE(component_manager_.SetStateProperty(
      "comp", "base.firmwareVersion", ver, nullptr));

  std::string ticket_url = expected_data.service_url + "registrationTickets/" +
                           expected_data.ticket_id;
  EXPECT_CALL(http_client_,
              SendRequest(HttpClient::Method::kPatch,
                          ticket_url + "?key=" + expected_data.api_key,
                          HttpClient::Headers{GetJsonHeader()}, _, _))
      .WillOnce(WithArgs<3, 4>(Invoke(
          [&expected_data](const std::string& data,
                           const HttpClient::SendRequestCallback& callback) {
            auto json = test::CreateDictionaryValue(data);
            EXPECT_NE(nullptr, json.get());
            std::string value;
            EXPECT_TRUE(json->GetString("id", &value));
            EXPECT_EQ(expected_data.ticket_id, value);
            EXPECT_TRUE(
                json->GetString("deviceDraft.channel.supportedType", &value));
            EXPECT_EQ("pull", value);
            EXPECT_TRUE(json->GetString("oauthClientId", &value));
            EXPECT_EQ(expected_data.client_id, 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* dict = nullptr;
            EXPECT_FALSE(json->GetDictionary("deviceDraft.commandDefs", &dict));
            EXPECT_FALSE(json->GetDictionary("deviceDraft.state", &dict));
            EXPECT_TRUE(json->GetDictionary("deviceDraft.traits", &dict));
            auto expectedTraits = R"({
              'base': {
                'commands': {
                  'reboot': {
                    'parameters': {'delay': {'minimum': 10, 'type': 'integer'}},
                    'minimalRole': 'user'
                  }
                },
                'state': {
                  'firmwareVersion': {'type': 'string'}
                }
              },
              'robot': {
                'commands': {
                  '_jump': {
                    'parameters': {'_height': {'type': 'integer'}},
                    'minimalRole': 'user'
                  }
                }
              }
            })";
            EXPECT_JSON_EQ(expectedTraits, *dict);

            EXPECT_TRUE(json->GetDictionary("deviceDraft.components", &dict));
            auto expectedComponents = R"({
              'comp': {
                'traits': ['base', 'robot'],
                'state': {
                  'base': { 'firmwareVersion': '1.0' }
                }
              }
            })";
            EXPECT_JSON_EQ(expectedComponents, *dict);

            base::DictionaryValue json_resp;
            json_resp.SetString("id", test_data::kClaimTicketId);
            json_resp.SetString("kind", "weave#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::kCloudId);
            device_draft->SetString("kind", "weave#device");
            json_resp.Set("deviceDraft", device_draft);

            callback.Run(ReplyWithJson(200, json_resp), nullptr);
          })));

  EXPECT_CALL(http_client_,
              SendRequest(HttpClient::Method::kPost,
                          ticket_url + "/finalize?key=" + expected_data.api_key,
                          HttpClient::Headers{}, _, _))
      .WillOnce(WithArgs<4>(
          Invoke([](const HttpClient::SendRequestCallback& callback) {
            base::DictionaryValue json;
            json.SetString("id", test_data::kClaimTicketId);
            json.SetString("kind", "weave#registrationTicket");
            json.SetString("oauthClientId", test_data::kClientId);
            json.SetString("userEmail", "user@email.com");
            json.SetString("deviceDraft.id", test_data::kCloudId);
            json.SetString("deviceDraft.kind", "weave#device");
            json.SetString("deviceDraft.channel.supportedType", "xmpp");
            json.SetString("robotAccountEmail", test_data::kRobotAccountEmail);
            json.SetString("robotAccountAuthorizationCode",
                           test_data::kRobotAccountAuthCode);
            callback.Run(ReplyWithJson(200, json), nullptr);
          })));

  EXPECT_CALL(
      http_client_,
      SendRequest(HttpClient::Method::kPost, expected_data.oauth_url + "token",
                  HttpClient::Headers{GetFormHeader()}, _, _))
      .WillOnce(WithArgs<3, 4>(Invoke([&expected_data](
          const std::string& data,
          const HttpClient::SendRequestCallback& callback) {
        EXPECT_EQ("authorization_code", GetFormField(data, "grant_type"));
        EXPECT_EQ(test_data::kRobotAccountAuthCode, GetFormField(data, "code"));
        EXPECT_EQ(expected_data.client_id, GetFormField(data, "client_id"));
        EXPECT_EQ(expected_data.client_secret,
                  GetFormField(data, "client_secret"));
        EXPECT_EQ("oob", GetFormField(data, "redirect_uri"));

        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);

        callback.Run(ReplyWithJson(200, json), nullptr);
      })));

  EXPECT_CALL(
      http_client_,
      SendRequest(HttpClient::Method::kPost,
                  expected_data.service_url + "devices/" + test_data::kCloudId +
                      "/upsertLocalAuthInfo",
                  HttpClient::Headers{GetAuthHeader(), GetJsonHeader()}, _, _))
      .WillOnce(WithArgs<3, 4>(
          Invoke([](const std::string& data,
                    const HttpClient::SendRequestCallback& callback) {
            auto dict = CreateDictionaryValue(data);
            EXPECT_TRUE(dict->Remove("localAuthInfo.clientToken", nullptr));
            EXPECT_JSON_EQ(test_data::kAuthInfo, *dict);
            base::DictionaryValue json;
            callback.Run(ReplyWithJson(200, json), nullptr);
          })));

  bool done = false;
  dev_reg_->RegisterDevice(
      registration_data,
      base::Bind([this, &done, &expected_data](ErrorPtr error) {
        done = true;
        task_runner_.Break();

        EXPECT_FALSE(error);
        EXPECT_EQ(GcdState::kConnecting, GetGcdState());

        // Validate the device info saved to storage...
        EXPECT_EQ(test_data::kCloudId, dev_reg_->GetSettings().cloud_id);
        EXPECT_EQ(test_data::kRefreshToken,
                  dev_reg_->GetSettings().refresh_token);
        EXPECT_EQ(test_data::kRobotAccountEmail,
                  dev_reg_->GetSettings().robot_account);
        EXPECT_EQ(expected_data.oauth_url, dev_reg_->GetSettings().oauth_url);
        EXPECT_EQ(expected_data.client_id, dev_reg_->GetSettings().client_id);
        EXPECT_EQ(expected_data.client_secret,
                  dev_reg_->GetSettings().client_secret);
        EXPECT_EQ(expected_data.api_key, dev_reg_->GetSettings().api_key);
        EXPECT_EQ(expected_data.service_url,
                  dev_reg_->GetSettings().service_url);
        EXPECT_EQ(expected_data.xmpp_endpoint,
                  dev_reg_->GetSettings().xmpp_endpoint);
      }));
  task_runner_.Run();
  EXPECT_TRUE(done);
}

TEST_F(DeviceRegistrationInfoTest, RegisterDevice) {
  ReloadSettings(false, true);

  RegistrationData registration_data;
  registration_data.ticket_id = "test_ticked_id";
  registration_data.oauth_url = "https://test.oauth/";
  registration_data.client_id = "test_client_id";
  registration_data.client_secret = "test_client_secret";
  registration_data.api_key = "test_api_key";
  registration_data.service_url = "https://test.service/";
  registration_data.xmpp_endpoint = "test.xmpp:1234";

  RegisterDevice(registration_data, registration_data);
}

TEST_F(DeviceRegistrationInfoTest, RegisterDeviceWithDefaultEndpoints) {
  ReloadSettings(false, true);

  RegistrationData registration_data;
  registration_data.ticket_id = "test_ticked_id";

  RegistrationData expected_data = registration_data;
  expected_data.oauth_url = test_data::kOAuthUrl;
  expected_data.client_id = test_data::kClientId;
  expected_data.client_secret = test_data::kClientSecret;
  expected_data.api_key = test_data::kApiKey;
  expected_data.service_url = test_data::kServiceUrl;
  expected_data.xmpp_endpoint = test_data::kXmppEndpoint;

  RegisterDevice(registration_data, expected_data);
}

TEST_F(DeviceRegistrationInfoTest, RegisterDeviceEndpointsOverrideNotAllowed) {
  ReloadSettings(false, false);

  RegistrationData registration_data;
  registration_data.ticket_id = "test_ticked_id";
  registration_data.service_url = "https://test.service/";

  bool done = false;
  dev_reg_->RegisterDevice(registration_data,
                           base::Bind([this, &done](ErrorPtr error) {
                             done = true;
                             task_runner_.Break();
                             EXPECT_TRUE(error->HasError("invalidParams"));
                           }));
  task_runner_.Run();
  EXPECT_TRUE(done);
}

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(GcdState::kUnconfigured, GetGcdState());
  // Put some credentials into our state, make sure we call that offline.
  ReloadSettings(true, false);
  EXPECT_EQ(GcdState::kConnecting, GetGcdState());
}

class DeviceRegistrationInfoUpdateCommandTest
    : public DeviceRegistrationInfoTest {
 protected:
  void SetUp() override {
    DeviceRegistrationInfoTest::SetUp();

    ReloadSettings(true, false);
    SetAccessToken();

    auto json_traits = CreateDictionaryValue(R"({
      'robot': {
        'commands': {
          '_jump': {
            'parameters': {'_height': 'integer'},
            'progress': {'progress': 'integer'},
            'results': {'status': 'string'},
            'minimalRole': 'user'
          }
        }
      }
    })");
    EXPECT_TRUE(component_manager_.LoadTraits(*json_traits, nullptr));
    EXPECT_TRUE(
        component_manager_.AddComponent("", "comp", {"robot"}, nullptr));

    command_url_ = dev_reg_->GetServiceUrl("commands/1234");

    auto commands_json = CreateValue(R"([{
      'name':'robot._jump',
      'component': 'comp',
      '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);
    command_ = component_manager_.FindCommand("1234");
    ASSERT_NE(nullptr, command_);
  }

  void TearDown() override {
    task_runner_.RunOnce();
    DeviceRegistrationInfoTest::TearDown();
  }

  Command* command_{nullptr};
  std::string command_url_;
};

TEST_F(DeviceRegistrationInfoUpdateCommandTest, SetProgress) {
  EXPECT_CALL(
      http_client_,
      SendRequest(HttpClient::Method::kPatch, command_url_,
                  HttpClient::Headers{GetAuthHeader(), GetJsonHeader()}, _, _))
      .WillOnce(WithArgs<3, 4>(Invoke([](
          const std::string& data,
          const HttpClient::SendRequestCallback& callback) {
        EXPECT_JSON_EQ((R"({"state":"inProgress","progress":{"progress":18}})"),
                       *CreateDictionaryValue(data));
        base::DictionaryValue json;
        callback.Run(ReplyWithJson(200, json), nullptr);
      })));
  EXPECT_TRUE(command_->SetProgress(*CreateDictionaryValue("{'progress':18}"),
                                    nullptr));
}

TEST_F(DeviceRegistrationInfoUpdateCommandTest, Complete) {
  EXPECT_CALL(
      http_client_,
      SendRequest(HttpClient::Method::kPatch, command_url_,
                  HttpClient::Headers{GetAuthHeader(), GetJsonHeader()}, _, _))
      .WillOnce(WithArgs<3, 4>(
          Invoke([](const std::string& data,
                    const HttpClient::SendRequestCallback& callback) {
            EXPECT_JSON_EQ(R"({"state":"done", "results":{"status":"Ok"}})",
                           *CreateDictionaryValue(data));
            base::DictionaryValue json;
            callback.Run(ReplyWithJson(200, json), nullptr);
          })));
  EXPECT_TRUE(
      command_->Complete(*CreateDictionaryValue("{'status': 'Ok'}"), nullptr));
}

TEST_F(DeviceRegistrationInfoUpdateCommandTest, Cancel) {
  EXPECT_CALL(
      http_client_,
      SendRequest(HttpClient::Method::kPatch, command_url_,
                  HttpClient::Headers{GetAuthHeader(), GetJsonHeader()}, _, _))
      .WillOnce(WithArgs<3, 4>(
          Invoke([](const std::string& data,
                    const HttpClient::SendRequestCallback& callback) {
            EXPECT_JSON_EQ(R"({"state":"cancelled"})",
                           *CreateDictionaryValue(data));
            base::DictionaryValue json;
            callback.Run(ReplyWithJson(200, json), nullptr);
          })));
  EXPECT_TRUE(command_->Cancel(nullptr));
}

}  // namespace weave
