// Copyright 2014 The Chromium 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 "chromeos/pairing/fake_controller_pairing_flow.h"

#include <map>

#include "base/bind.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/rand_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"

namespace chromeos {

FakeControllerPairingFlow::FakeControllerPairingFlow(const std::string& config)
    : current_stage_(STAGE_NONE),
      should_fail_on_connecting_(false),
      connection_lost_begin_(STAGE_NONE),
      connection_lost_end_(STAGE_NONE),
      enrollment_should_fail_(false) {
  ApplyConfig(config);
  AddObserver(this);
}

FakeControllerPairingFlow::~FakeControllerPairingFlow() {
  RemoveObserver(this);
}

void FakeControllerPairingFlow::ApplyConfig(const std::string& config) {
  typedef std::vector<std::string> Tokens;

  base::StringPairs kv_pairs;
  CHECK(base::SplitStringIntoKeyValuePairs(config, ':', ',', &kv_pairs))
      << "Wrong config format.";
  std::map<std::string, std::string> dict(kv_pairs.begin(), kv_pairs.end());

  if (dict.count("async_duration")) {
    int ms = 0;
    CHECK(base::StringToInt(dict["async_duration"], &ms))
        << "Wrong 'async_duration' format.";
    async_duration_ = base::TimeDelta::FromMilliseconds(ms);
  } else {
    async_duration_ = base::TimeDelta::FromMilliseconds(3000);
  }

  should_fail_on_connecting_ =
      dict.count("fail_connecting") && (dict["fail_connecting"] == "1");

  enrollment_should_fail_ =
      dict.count("fail_enrollment") && (dict["fail_enrollment"] == "1");

  if (dict.count("connection_lost")) {
    Tokens lost_begin_end;
    CHECK(Tokenize(dict["connection_lost"], "-", &lost_begin_end) == 2)
        << "Wrong 'connection_lost' format.";
    int begin = 0;
    int end = 0;
    CHECK(base::StringToInt(lost_begin_end[0], &begin) &&
          base::StringToInt(lost_begin_end[1], &end))
        << "Wrong 'connection_lost' format.";
    CHECK((begin == 0 && end == 0) ||
          (STAGE_WAITING_FOR_CODE_CONFIRMATION <= begin && begin <= end &&
           end <= STAGE_HOST_ENROLLMENT_ERROR))
        << "Wrong 'connection_lost' interval.";
    connection_lost_begin_ = static_cast<Stage>(begin);
    connection_lost_end_ = static_cast<Stage>(end);
  } else {
    connection_lost_begin_ = connection_lost_end_ = STAGE_NONE;
  }

  if (!dict.count("discovery")) {
    dict["discovery"] =
        "F-Device_1~F-Device_5~F-Device_3~L-Device_3~L-Device_1~F-Device_1";
  }
  base::StringPairs events;
  CHECK(
      base::SplitStringIntoKeyValuePairs(dict["discovery"], '-', '~', &events))
      << "Wrong 'discovery' format.";
  DiscoveryScenario scenario;
  for (base::StringPairs::const_iterator event = events.begin();
       event != events.end();
       ++event) {
    std::string type = event->first;
    std::string device_id = event->second;
    CHECK(type == "F" || type == "L" || type == "N")
        << "Wrong discovery event type.";
    CHECK(!device_id.empty() || type == "N") << "Empty device ID.";
    scenario.push_back(DiscoveryEvent(
        type == "F" ? DEVICE_FOUND : type == "L" ? DEVICE_LOST : NOTHING_FOUND,
        device_id));
  }
  SetDiscoveryScenario(scenario);

  preset_confirmation_code_ = dict["code"];
  CHECK(preset_confirmation_code_.empty() ||
        (preset_confirmation_code_.length() == 6 &&
         preset_confirmation_code_.find_first_not_of("0123456789") ==
             std::string::npos))
      << "Wrong 'code' format.";
}

void FakeControllerPairingFlow::SetShouldFailOnConnecting() {
  should_fail_on_connecting_ = true;
}

void FakeControllerPairingFlow::SetShouldLoseConnection(Stage stage_begin,
                                                        Stage stage_end) {
  connection_lost_begin_ = stage_begin;
  connection_lost_end_ = stage_end;
}

void FakeControllerPairingFlow::SetEnrollmentShouldFail() {
  enrollment_should_fail_ = true;
}

void FakeControllerPairingFlow::SetDiscoveryScenario(
    const DiscoveryScenario& discovery_scenario) {
  discovery_scenario_ = discovery_scenario;
  // Check that scenario is valid.
  std::set<std::string> devices;
  for (DiscoveryScenario::const_iterator event = discovery_scenario_.begin();
       event != discovery_scenario_.end();
       ++event) {
    switch (event->first) {
      case DEVICE_FOUND: {
        devices.insert(event->second);
        break;
      }
      case DEVICE_LOST: {
        CHECK(devices.count(event->second));
        devices.erase(event->second);
        break;
      }
      case NOTHING_FOUND: {
        CHECK(++event == discovery_scenario_.end());
        return;
      }
    }
  }
}

void FakeControllerPairingFlow::AddObserver(Observer* observer) {
  observers_.AddObserver(observer);
}

void FakeControllerPairingFlow::RemoveObserver(Observer* observer) {
  observers_.RemoveObserver(observer);
}

ControllerPairingFlow::Stage FakeControllerPairingFlow::GetCurrentStage() {
  return current_stage_;
}

void FakeControllerPairingFlow::StartFlow() {
  CHECK(current_stage_ == STAGE_NONE);
  ChangeStage(STAGE_DEVICES_DISCOVERY);
}

ControllerPairingFlow::DeviceIdList
FakeControllerPairingFlow::GetDiscoveredDevices() {
  CHECK(current_stage_ == STAGE_DEVICES_DISCOVERY);
  return DeviceIdList(discovered_devices_.begin(), discovered_devices_.end());
}

void FakeControllerPairingFlow::ChooseDeviceForPairing(
    const std::string& device_id) {
  CHECK(current_stage_ == STAGE_DEVICES_DISCOVERY);
  CHECK(discovered_devices_.count(device_id));
  choosen_device_ = device_id;
  ChangeStage(STAGE_ESTABLISHING_CONNECTION);
}

void FakeControllerPairingFlow::RepeatDiscovery() {
  CHECK(current_stage_ == STAGE_DEVICE_NOT_FOUND ||
        current_stage_ == STAGE_ESTABLISHING_CONNECTION_ERROR ||
        current_stage_ == STAGE_HOST_ENROLLMENT_ERROR);
  ChangeStage(STAGE_DEVICES_DISCOVERY);
}

std::string FakeControllerPairingFlow::GetConfirmationCode() {
  CHECK(current_stage_ == STAGE_WAITING_FOR_CODE_CONFIRMATION);
  if (confirmation_code_.empty()) {
    if (preset_confirmation_code_.empty()) {
      for (int i = 0; i < 6; ++i)
        confirmation_code_.push_back(base::RandInt('0', '9'));
    } else {
      confirmation_code_ = preset_confirmation_code_;
    }
  }
  return confirmation_code_;
}

void FakeControllerPairingFlow::SetConfirmationCodeIsCorrect(bool correct) {
  CHECK(current_stage_ == STAGE_WAITING_FOR_CODE_CONFIRMATION);
  if (correct)
    ChangeStage(STAGE_HOST_UPDATE_IN_PROGRESS);
  else
    ChangeStage(STAGE_DEVICES_DISCOVERY);
}

void FakeControllerPairingFlow::OnAuthenticationDone(
    const chromeos::UserContext& user_context,
    content::BrowserContext* browser_context) {
  CHECK(current_stage_ == STAGE_WAITING_FOR_CREDENTIALS);
  ChangeStage(STAGE_HOST_ENROLLMENT_IN_PROGRESS);
}

void FakeControllerPairingFlow::StartSession() {
  CHECK(current_stage_ == STAGE_PAIRING_DONE);
  ChangeStage(STAGE_FINISHED);
}

void FakeControllerPairingFlow::ChangeStage(Stage new_stage) {
  if (current_stage_ == new_stage)
    return;
  current_stage_ = new_stage;
  FOR_EACH_OBSERVER(Observer, observers_, PairingStageChanged(new_stage));
}

void FakeControllerPairingFlow::ChangeStageLater(Stage new_stage) {
  base::MessageLoop::current()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&FakeControllerPairingFlow::ChangeStage,
                 base::Unretained(this),
                 new_stage),
      async_duration_);
}

void FakeControllerPairingFlow::ExecuteDiscoveryEvent(size_t event_position) {
  if (current_stage_ != STAGE_DEVICES_DISCOVERY)
    return;
  CHECK(event_position < discovery_scenario_.size());
  const DiscoveryEvent& event = discovery_scenario_[event_position];
  switch (event.first) {
    case DEVICE_FOUND: {
      DeviceFound(event.second);
      break;
    }
    case DEVICE_LOST: {
      DeviceLost(event.second);
      break;
    }
    case NOTHING_FOUND: {
      ChangeStage(STAGE_DEVICE_NOT_FOUND);
      break;
    }
  }
  if (++event_position == discovery_scenario_.size()) {
    return;
  }
  base::MessageLoop::current()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&FakeControllerPairingFlow::ExecuteDiscoveryEvent,
                 base::Unretained(this),
                 event_position),
      async_duration_);
}

void FakeControllerPairingFlow::DeviceFound(const std::string& device_id) {
  CHECK(current_stage_ == STAGE_DEVICES_DISCOVERY);
  discovered_devices_.insert(device_id);
  FOR_EACH_OBSERVER(Observer, observers_, DiscoveredDevicesListChanged());
}

void FakeControllerPairingFlow::DeviceLost(const std::string& device_id) {
  CHECK(current_stage_ == STAGE_DEVICES_DISCOVERY);
  discovered_devices_.erase(device_id);
  FOR_EACH_OBSERVER(Observer, observers_, DiscoveredDevicesListChanged());
}

void FakeControllerPairingFlow::PairingStageChanged(Stage new_stage) {
  Stage next_stage = STAGE_NONE;
  switch (new_stage) {
    case STAGE_DEVICES_DISCOVERY: {
      discovered_devices_.clear();
      base::MessageLoop::current()->PostDelayedTask(
          FROM_HERE,
          base::Bind(&FakeControllerPairingFlow::ExecuteDiscoveryEvent,
                     base::Unretained(this),
                     0),
          async_duration_);
      break;
    }
    case STAGE_ESTABLISHING_CONNECTION: {
      if (should_fail_on_connecting_) {
        next_stage = STAGE_ESTABLISHING_CONNECTION_ERROR;
        should_fail_on_connecting_ = false;
      } else {
        confirmation_code_.clear();
        next_stage = STAGE_WAITING_FOR_CODE_CONFIRMATION;
      }
      break;
    }
    case STAGE_HOST_UPDATE_IN_PROGRESS: {
      next_stage = STAGE_WAITING_FOR_CREDENTIALS;
      break;
    }
    case STAGE_HOST_ENROLLMENT_IN_PROGRESS: {
      if (enrollment_should_fail_) {
        enrollment_should_fail_ = false;
        next_stage = STAGE_HOST_ENROLLMENT_ERROR;
      } else {
        next_stage = STAGE_PAIRING_DONE;
      }
      break;
    }
    case STAGE_HOST_CONNECTION_LOST: {
      next_stage = connection_lost_end_;
      connection_lost_end_ = STAGE_NONE;
      break;
    }
    default:
      break;
  }
  if (new_stage == connection_lost_begin_) {
    connection_lost_begin_ = STAGE_NONE;
    next_stage = STAGE_HOST_CONNECTION_LOST;
  }
  if (next_stage != STAGE_NONE)
    ChangeStageLater(next_stage);
}

void FakeControllerPairingFlow::DiscoveredDevicesListChanged() {
}

}  // namespace chromeos
