// 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 <weave/device.h>

#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <weave/provider/test/fake_task_runner.h>
#include <weave/provider/test/mock_bluetooth.h>
#include <weave/provider/test/mock_config_store.h>
#include <weave/provider/test/mock_dns_service_discovery.h>
#include <weave/provider/test/mock_http_client.h>
#include <weave/provider/test/mock_http_server.h>
#include <weave/provider/test/mock_network.h>
#include <weave/provider/test/mock_wifi.h>
#include <weave/test/mock_command.h>
#include <weave/test/mock_device.h>
#include <weave/test/unittest_utils.h>

#include "src/bind_lambda.h"

using testing::_;
using testing::AtLeast;
using testing::AtMost;
using testing::HasSubstr;
using testing::InSequence;
using testing::Invoke;
using testing::InvokeWithoutArgs;
using testing::MatchesRegex;
using testing::Mock;
using testing::Return;
using testing::ReturnRefOfCopy;
using testing::StartsWith;
using testing::StrictMock;
using testing::WithArgs;

namespace weave {

namespace {

using provider::HttpClient;
using provider::Network;
using provider::test::MockHttpClientResponse;
using test::CreateDictionaryValue;
using test::ValueToString;

const char kTraitDefs[] = R"({
  "trait1": {
    "commands": {
      "reboot": {
        "minimalRole": "user"
      },
      "shutdown": {
        "minimalRole": "user",
        "parameters": {},
        "results": {}
      }
    },
    "state": {
      "firmwareVersion": {"type": "string"}
    }
  },
  "trait2": {
    "state": {
      "battery_level": {"type": "integer"}
    }
  }
})";

const char kDeviceResource[] = R"({
  "kind": "weave#device",
  "id": "CLOUD_ID",
  "channel": {
    "supportedType": "pull"
  },
  "deviceKind": "vendor",
  "modelManifestId": "ABCDE",
  "systemName": "",
  "name": "TEST_NAME",
  "displayName": "",
  "description": "Developer device",
  "stateValidationEnabled": true,
  "commandDefs":{
    "trait1": {
      "reboot": {
        "minimalRole": "user",
        "parameters": {"delay": {"type": "integer"}},
        "results": {}
      },
      "shutdown": {
        "minimalRole": "user",
        "parameters": {},
        "results": {}
      }
    }
  },
  "state":{
    "trait1": {"firmwareVersion":"FIRMWARE_VERSION"},
    "trait2": {"battery_level":44}
  },
  "traits": {
    "trait1": {
      "commands": {
        "reboot": {
          "minimalRole": "user"
        },
        "shutdown": {
          "minimalRole": "user",
          "parameters": {},
          "results": {}
        }
      },
      "state": {
        "firmwareVersion": {"type": "string"}
      }
    },
    "trait2": {
      "state": {
        "battery_level": {"type": "integer"}
      }
    }
  },
  "components": {
    "myComponent": {
      "traits": ["trait1", "trait2"],
      "state": {
        "trait1": {"firmwareVersion":"FIRMWARE_VERSION"},
        "trait2": {"battery_level":44}
      }
    }
  }
})";

const char kRegistrationResponse[] = R"({
  "kind": "weave#registrationTicket",
  "id": "TICKET_ID",
  "deviceId": "CLOUD_ID",
  "oauthClientId": "CLIENT_ID",
  "userEmail": "USER@gmail.com",
  "creationTimeMs": "1440087183738",
  "expirationTimeMs": "1440087423738"
})";

const char kRegistrationFinalResponse[] = R"({
  "kind": "weave#registrationTicket",
  "id": "TICKET_ID",
  "deviceId": "CLOUD_ID",
  "oauthClientId": "CLIENT_ID",
  "userEmail": "USER@gmail.com",
  "robotAccountEmail": "ROBO@gmail.com",
  "robotAccountAuthorizationCode": "AUTH_CODE",
  "creationTimeMs": "1440087183738",
  "expirationTimeMs": "1440087423738"
})";

const char kAuthTokenResponse[] = R"({
  "access_token" : "ACCESS_TOKEN",
  "token_type" : "Bearer",
  "expires_in" : 3599,
  "refresh_token" : "REFRESH_TOKEN"
})";

MATCHER_P(MatchTxt, txt, "") {
  std::vector<std::string> txt_copy = txt;
  std::sort(txt_copy.begin(), txt_copy.end());
  std::vector<std::string> arg_copy = arg;
  std::sort(arg_copy.begin(), arg_copy.end());
  return (arg_copy == txt_copy);
}

template <class Map>
std::set<typename Map::key_type> GetKeys(const Map& map) {
  std::set<typename Map::key_type> result;
  for (const auto& pair : map)
    result.insert(pair.first);
  return result;
}

}  // namespace

class WeaveTest : public ::testing::Test {
 protected:
  void SetUp() override {
    EXPECT_CALL(wifi_, IsWifi24Supported()).WillRepeatedly(Return(true));
    EXPECT_CALL(wifi_, IsWifi50Supported()).WillRepeatedly(Return(false));
  }

  template <class UrlMatcher>
  void ExpectRequest(HttpClient::Method method,
                     const UrlMatcher& url_matcher,
                     const std::string& json_response) {
    EXPECT_CALL(http_client_, SendRequest(method, url_matcher, _, _, _))
        .WillOnce(WithArgs<4>(Invoke(
            [json_response](const HttpClient::SendRequestCallback& callback) {
              std::unique_ptr<provider::test::MockHttpClientResponse> response{
                  new StrictMock<provider::test::MockHttpClientResponse>};
              EXPECT_CALL(*response, GetStatusCode())
                  .Times(AtLeast(1))
                  .WillRepeatedly(Return(200));
              EXPECT_CALL(*response, GetContentType())
                  .Times(AtLeast(1))
                  .WillRepeatedly(Return("application/json; charset=utf-8"));
              EXPECT_CALL(*response, GetData())
                  .WillRepeatedly(Return(json_response));
              callback.Run(std::move(response), nullptr);
            })));
  }

  void InitNetwork() {
    EXPECT_CALL(network_, AddConnectionChangedCallback(_))
        .WillRepeatedly(Invoke(
            [this](const provider::Network::ConnectionChangedCallback& cb) {
              network_callbacks_.push_back(cb);
            }));
    EXPECT_CALL(network_, GetConnectionState())
        .WillRepeatedly(Return(Network::State::kOffline));
  }

  void InitDnsSd() {
    EXPECT_CALL(dns_sd_, PublishService(_, _, _)).WillRepeatedly(Return());
    EXPECT_CALL(dns_sd_, StopPublishing("_privet._tcp")).WillOnce(Return());
  }

  void InitDnsSdPublishing(bool registered, const std::string& flags) {
    std::vector<std::string> txt{
        {"id=TEST_DEVICE_ID"},         {"flags=" + flags}, {"mmid=ABCDE"},
        {"services=developmentBoard"}, {"txtvers=3"},      {"ty=TEST_NAME"}};
    if (registered) {
      txt.push_back("gcd_id=CLOUD_ID");

      // During registration device may announce itself twice:
      // 1. with GCD ID but not connected (DB)
      // 2. with GCD ID and connected (BB)
      EXPECT_CALL(dns_sd_, PublishService("_privet._tcp", 11, MatchTxt(txt)))
          .Times(AtMost(1))
          .WillOnce(Return());

      txt[1] = "flags=BB";
    }

    EXPECT_CALL(dns_sd_, PublishService("_privet._tcp", 11, MatchTxt(txt)))
        .Times(AtMost(1))
        .WillOnce(Return());
  }

  void InitHttpServer() {
    EXPECT_CALL(http_server_, GetHttpPort()).WillRepeatedly(Return(11));
    EXPECT_CALL(http_server_, GetHttpsPort()).WillRepeatedly(Return(12));
    EXPECT_CALL(http_server_, GetRequestTimeout())
        .WillRepeatedly(Return(base::TimeDelta::Max()));
    EXPECT_CALL(http_server_, GetHttpsCertificateFingerprint())
        .WillRepeatedly(Return(std::vector<uint8_t>{1, 2, 3}));
    EXPECT_CALL(http_server_, AddHttpRequestHandler(_, _))
        .WillRepeatedly(Invoke(
            [this](const std::string& path_prefix,
                   const provider::HttpServer::RequestHandlerCallback& cb) {
              http_handlers_[path_prefix] = cb;
            }));
    EXPECT_CALL(http_server_, AddHttpsRequestHandler(_, _))
        .WillRepeatedly(Invoke(
            [this](const std::string& path_prefix,
                   const provider::HttpServer::RequestHandlerCallback& cb) {
              https_handlers_[path_prefix] = cb;
            }));
  }

  void InitDefaultExpectations() {
    InitNetwork();
    EXPECT_CALL(wifi_, StartAccessPoint(MatchesRegex("TEST_NAME.*prv")))
        .WillOnce(Return());
    InitHttpServer();
    InitDnsSd();
  }

  void StartDevice() {
    device_ = weave::Device::Create(&config_store_, &task_runner_,
                                    &http_client_, &network_, &dns_sd_,
                                    &http_server_, &wifi_, &bluetooth_);

    EXPECT_EQ((std::set<std::string>{
                  // clang-format off
                  "/privet/info",
                  "/privet/v3/pairing/cancel",
                  "/privet/v3/pairing/confirm",
                  "/privet/v3/pairing/start",
                  // clang-format on
              }),
              GetKeys(http_handlers_));
    EXPECT_EQ((std::set<std::string>{
                  // clang-format off
                  "/privet/info",
                  "/privet/v3/accessControl/claim",
                  "/privet/v3/accessControl/confirm",
                  "/privet/v3/auth",
                  "/privet/v3/checkForUpdates",
                  "/privet/v3/commands/cancel",
                  "/privet/v3/commands/execute",
                  "/privet/v3/commands/list",
                  "/privet/v3/commands/status",
                  "/privet/v3/components",
                  "/privet/v3/pairing/cancel",
                  "/privet/v3/pairing/confirm",
                  "/privet/v3/pairing/start",
                  "/privet/v3/setup/start",
                  "/privet/v3/setup/status",
                  "/privet/v3/traits",
                  // clang-format on
              }),
              GetKeys(https_handlers_));

    device_->AddTraitDefinitionsFromJson(kTraitDefs);
    EXPECT_TRUE(
        device_->AddComponent("myComponent", {"trait1", "trait2"}, nullptr));
    EXPECT_TRUE(device_->SetStatePropertiesFromJson(
        "myComponent", R"({"trait2": {"battery_level":44}})", nullptr));

    task_runner_.Run();
  }

  void NotifyNetworkChanged(provider::Network::State state,
                            base::TimeDelta delay) {
    auto task = [this, state] {
      EXPECT_CALL(network_, GetConnectionState()).WillRepeatedly(Return(state));
      for (const auto& cb : network_callbacks_)
        cb.Run();
    };

    task_runner_.PostDelayedTask(FROM_HERE, base::Bind(task), delay);
  }

  std::map<std::string, provider::HttpServer::RequestHandlerCallback>
      http_handlers_;
  std::map<std::string, provider::HttpServer::RequestHandlerCallback>
      https_handlers_;

  StrictMock<provider::test::MockConfigStore> config_store_;
  StrictMock<provider::test::FakeTaskRunner> task_runner_;
  StrictMock<provider::test::MockHttpClient> http_client_;
  StrictMock<provider::test::MockNetwork> network_;
  StrictMock<provider::test::MockDnsServiceDiscovery> dns_sd_;
  StrictMock<provider::test::MockHttpServer> http_server_;
  StrictMock<provider::test::MockWifi> wifi_;
  StrictMock<provider::test::MockBluetooth> bluetooth_;

  std::vector<provider::Network::ConnectionChangedCallback> network_callbacks_;

  std::unique_ptr<weave::Device> device_;
};

TEST_F(WeaveTest, Mocks) {
  // Test checks if mock implements entire interface and mock can be
  // instantiated.
  test::MockDevice device;
  test::MockCommand command;
}

TEST_F(WeaveTest, StartMinimal) {
  device_ = weave::Device::Create(&config_store_, &task_runner_, &http_client_,
                                  &network_, nullptr, nullptr, &wifi_, nullptr);
}

TEST_F(WeaveTest, StartNoWifi) {
  InitNetwork();
  InitHttpServer();
  InitDnsSd();
  InitDnsSdPublishing(false, "CB");

  device_ = weave::Device::Create(&config_store_, &task_runner_, &http_client_,
                                  &network_, &dns_sd_, &http_server_, nullptr,
                                  &bluetooth_);
  device_->AddTraitDefinitionsFromJson(kTraitDefs);
  EXPECT_TRUE(
      device_->AddComponent("myComponent", {"trait1", "trait2"}, nullptr));

  task_runner_.Run();
}

class WeaveBasicTest : public WeaveTest {
 public:
  void SetUp() override {
    WeaveTest::SetUp();

    InitDefaultExpectations();
    InitDnsSdPublishing(false, "DB");
  }
};

TEST_F(WeaveBasicTest, Start) {
  StartDevice();
}

TEST_F(WeaveBasicTest, Register) {
  EXPECT_CALL(network_, OpenSslSocket(_, _, _)).WillRepeatedly(Return());
  StartDevice();

  auto draft = CreateDictionaryValue(kDeviceResource);
  auto response = CreateDictionaryValue(kRegistrationResponse);
  response->Set("deviceDraft", draft->DeepCopy());
  ExpectRequest(HttpClient::Method::kPatch,
                "https://www.googleapis.com/weave/v1/registrationTickets/"
                "TICKET_ID?key=TEST_API_KEY",
                ValueToString(*response));

  response = CreateDictionaryValue(kRegistrationFinalResponse);
  response->Set("deviceDraft", draft->DeepCopy());
  ExpectRequest(HttpClient::Method::kPost,
                "https://www.googleapis.com/weave/v1/registrationTickets/"
                "TICKET_ID/finalize?key=TEST_API_KEY",
                ValueToString(*response));

  ExpectRequest(HttpClient::Method::kPost,
                "https://accounts.google.com/o/oauth2/token",
                kAuthTokenResponse);

  ExpectRequest(HttpClient::Method::kPost, HasSubstr("upsertLocalAuthInfo"),
                {});

  InitDnsSdPublishing(true, "DB");

  bool done = false;
  device_->Register(RegistrationData{"TICKET_ID"},
                    base::Bind([this, &done](ErrorPtr error) {
                      EXPECT_FALSE(error);
                      done = true;
                      task_runner_.Break();
                      EXPECT_EQ("CLOUD_ID", device_->GetSettings().cloud_id);
                    }));
  task_runner_.Run();
  EXPECT_TRUE(done);

  done = false;
  device_->Register(RegistrationData{"TICKET_ID2"},
                    base::Bind([this, &done](ErrorPtr error) {
                      EXPECT_TRUE(error->HasError("already_registered"));
                      done = true;
                      task_runner_.Break();
                      EXPECT_EQ("CLOUD_ID", device_->GetSettings().cloud_id);
                    }));
  task_runner_.Run();
  EXPECT_TRUE(done);
}

class WeaveWiFiSetupTest : public WeaveTest {
 public:
  void SetUp() override {
    WeaveTest::SetUp();

    InitHttpServer();
    InitNetwork();
    InitDnsSd();

    EXPECT_CALL(network_, GetConnectionState())
        .WillRepeatedly(Return(provider::Network::State::kOnline));
  }
};

TEST_F(WeaveWiFiSetupTest, StartOnlineNoPrevSsid) {
  StartDevice();

  // Short disconnect.
  NotifyNetworkChanged(provider::Network::State::kOffline, {});
  NotifyNetworkChanged(provider::Network::State::kOnline,
                       base::TimeDelta::FromSeconds(10));
  task_runner_.Run();

  // Long disconnect.
  NotifyNetworkChanged(Network::State::kOffline, {});
  auto offline_from = task_runner_.GetClock()->Now();
  EXPECT_CALL(wifi_, StartAccessPoint(MatchesRegex("TEST_NAME.*prv")))
      .WillOnce(InvokeWithoutArgs([this, offline_from]() {
        EXPECT_GT(task_runner_.GetClock()->Now() - offline_from,
                  base::TimeDelta::FromMinutes(1));
        task_runner_.Break();
      }));
  task_runner_.Run();
}

// If device has previously configured WiFi it will run AP for limited time
// after which it will try to re-connect.
TEST_F(WeaveWiFiSetupTest, StartOnlineWithPrevSsid) {
  EXPECT_CALL(config_store_, LoadSettings())
      .WillRepeatedly(Return(R"({"last_configured_ssid": "TEST_ssid"})"));
  StartDevice();

  // Long disconnect.
  NotifyNetworkChanged(Network::State::kOffline, {});

  for (int i = 0; i < 5; ++i) {
    auto offline_from = task_runner_.GetClock()->Now();
    // Temporarily offline mode.
    EXPECT_CALL(wifi_, StartAccessPoint(MatchesRegex("TEST_NAME.*prv")))
        .WillOnce(InvokeWithoutArgs([this, &offline_from]() {
          EXPECT_GT(task_runner_.GetClock()->Now() - offline_from,
                    base::TimeDelta::FromMinutes(1));
          task_runner_.Break();
        }));
    task_runner_.Run();

    // Try to reconnect again.
    offline_from = task_runner_.GetClock()->Now();
    EXPECT_CALL(wifi_, StopAccessPoint())
        .WillOnce(InvokeWithoutArgs([this, offline_from]() {
          EXPECT_GT(task_runner_.GetClock()->Now() - offline_from,
                    base::TimeDelta::FromMinutes(5));
          task_runner_.Break();
        }));
    task_runner_.Run();
  }

  NotifyNetworkChanged(Network::State::kOnline, {});
  task_runner_.Run();
}

TEST_F(WeaveWiFiSetupTest, StartOfflineWithSsid) {
  EXPECT_CALL(config_store_, LoadSettings())
      .WillRepeatedly(Return(R"({"last_configured_ssid": "TEST_ssid"})"));
  EXPECT_CALL(network_, GetConnectionState())
      .WillRepeatedly(Return(Network::State::kOffline));

  auto offline_from = task_runner_.GetClock()->Now();
  EXPECT_CALL(wifi_, StartAccessPoint(MatchesRegex("TEST_NAME.*prv")))
      .WillOnce(InvokeWithoutArgs([this, &offline_from]() {
        EXPECT_GT(task_runner_.GetClock()->Now() - offline_from,
                  base::TimeDelta::FromMinutes(1));
        task_runner_.Break();
      }));

  StartDevice();
}

TEST_F(WeaveWiFiSetupTest, OfflineLongTimeWithNoSsid) {
  EXPECT_CALL(network_, GetConnectionState())
      .WillRepeatedly(Return(Network::State::kOffline));
  NotifyNetworkChanged(provider::Network::State::kOnline,
                       base::TimeDelta::FromHours(15));

  {
    InSequence s;
    auto time_stamp = task_runner_.GetClock()->Now();

    EXPECT_CALL(wifi_, StartAccessPoint(MatchesRegex("TEST_NAME.*prv")))
        .WillOnce(InvokeWithoutArgs([this, &time_stamp]() {
          EXPECT_LE(task_runner_.GetClock()->Now() - time_stamp,
                    base::TimeDelta::FromMinutes(1));
          time_stamp = task_runner_.GetClock()->Now();
        }));

    EXPECT_CALL(wifi_, StopAccessPoint())
        .WillOnce(InvokeWithoutArgs([this, &time_stamp]() {
          EXPECT_GT(task_runner_.GetClock()->Now() - time_stamp,
                    base::TimeDelta::FromMinutes(5));
          time_stamp = task_runner_.GetClock()->Now();
          task_runner_.Break();
        }));
  }

  StartDevice();
}

TEST_F(WeaveWiFiSetupTest, OfflineLongTimeWithSsid) {
  EXPECT_CALL(config_store_, LoadSettings())
      .WillRepeatedly(Return(R"({"last_configured_ssid": "TEST_ssid"})"));
  EXPECT_CALL(network_, GetConnectionState())
      .WillRepeatedly(Return(Network::State::kOffline));
  NotifyNetworkChanged(provider::Network::State::kOnline,
                       base::TimeDelta::FromHours(15));

  {
    InSequence s;
    auto time_stamp = task_runner_.GetClock()->Now();
    for (size_t i = 0; i < 10; ++i) {
      EXPECT_CALL(wifi_, StartAccessPoint(MatchesRegex("TEST_NAME.*prv")))
          .WillOnce(InvokeWithoutArgs([this, &time_stamp]() {
            EXPECT_GT(task_runner_.GetClock()->Now() - time_stamp,
                      base::TimeDelta::FromMinutes(1));
            time_stamp = task_runner_.GetClock()->Now();
          }));

      EXPECT_CALL(wifi_, StopAccessPoint())
          .WillOnce(InvokeWithoutArgs([this, &time_stamp]() {
            EXPECT_GT(task_runner_.GetClock()->Now() - time_stamp,
                      base::TimeDelta::FromMinutes(5));
            time_stamp = task_runner_.GetClock()->Now();
          }));
    }

    EXPECT_CALL(wifi_, StartAccessPoint(MatchesRegex("TEST_NAME.*prv")))
        .WillOnce(InvokeWithoutArgs([this]() { task_runner_.Break(); }));
  }

  StartDevice();
}

}  // namespace weave
