// Copyright 2019 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 "remoting/test/it2me_cli_host.h"

#include "base/bind.h"
#include "base/command_line.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/run_loop.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "net/base/network_change_notifier.h"
#include "remoting/base/auto_thread_task_runner.h"
#include "remoting/base/logging.h"
#include "remoting/host/chromoting_host_context.h"
#include "remoting/host/it2me/it2me_native_messaging_host.h"
#include "remoting/host/policy_watcher.h"
#include "remoting/test/test_oauth_token_getter.h"
#include "remoting/test/test_token_storage.h"

namespace remoting {

namespace {

// Communication with CRD Host, messages sent to host:
constexpr char kCRDMessageTypeKey[] = "type";

constexpr char kCRDMessageHello[] = "hello";
constexpr char kCRDMessageConnect[] = "connect";
constexpr char kCRDMessageDisconnect[] = "disconnect";

// Communication with CRD Host, messages received from host:
constexpr char kCRDResponseHello[] = "helloResponse";
constexpr char kCRDResponseConnect[] = "connectResponse";
constexpr char kCRDStateChanged[] = "hostStateChanged";
constexpr char kCRDResponseDisconnect[] = "disconnectResponse";
constexpr char kCRDDebugLog[] = "_debug_log";

// Connect message parameters:
constexpr char kCRDConnectUserName[] = "userName";
constexpr char kCRDConnectAuth[] = "authServiceWithToken";
constexpr char kCRDConnectSuppressUserDialogs[] = "suppressUserDialogs";
constexpr char kCRDConnectSuppressNotifications[] = "suppressNotifications";

// CRD host states we care about:
constexpr char kCRDStateKey[] = "state";
constexpr char kCRDStateError[] = "ERROR";
constexpr char kCRDStateStarting[] = "STARTING";
constexpr char kCRDStateAccessCodeRequested[] = "REQUESTED_ACCESS_CODE";
constexpr char kCRDStateDomainError[] = "INVALID_DOMAIN_ERROR";
constexpr char kCRDStateAccessCode[] = "RECEIVED_ACCESS_CODE";
constexpr char kCRDStateRemoteDisconnected[] = "DISCONNECTED";
constexpr char kCRDStateRemoteConnected[] = "CONNECTED";

constexpr char kCRDErrorCodeKey[] = "error_code";
constexpr char kCRDAccessCodeKey[] = "accessCode";
constexpr char kCRDAccessCodeLifetimeKey[] = "accessCodeLifetime";

constexpr char kCRDConnectClientKey[] = "client";

constexpr char kSwitchNameHelp[] = "help";
constexpr char kSwitchNameUsername[] = "username";
constexpr char kSwitchNameStoragePath[] = "storage-path";

std::unique_ptr<It2MeNativeMessagingHost> CreateNativeMessagingHost(
    scoped_refptr<AutoThreadTaskRunner> ui_task_runner) {
  auto context = ChromotingHostContext::Create(ui_task_runner);
  std::unique_ptr<PolicyWatcher> policy_watcher =
      PolicyWatcher::CreateWithTaskRunner(context->file_task_runner());
  auto factory = std::make_unique<It2MeHostFactory>();
  return std::make_unique<It2MeNativeMessagingHost>(
      /* needs_elevation */ false, std::move(policy_watcher),
      std::move(context), std::move(factory));
}

}  // namespace

// static
bool It2MeCliHost::ShouldPrintHelp() {
  return base::CommandLine::ForCurrentProcess()->HasSwitch(kSwitchNameHelp);
}

// static
void It2MeCliHost::PrintHelp() {
  fprintf(stderr,
          "Usage: %s [--storage-path=<storage-path>] "
          "[--username=<example@gmail.com>]\n ",
          base::CommandLine::ForCurrentProcess()
              ->GetProgram()
              .AsUTF8Unsafe()
              .c_str());
}

It2MeCliHost::It2MeCliHost() {}
It2MeCliHost::~It2MeCliHost() = default;

void It2MeCliHost::Start() {
  base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
  std::string username = cmd_line->GetSwitchValueASCII(kSwitchNameUsername);
  base::FilePath storage_path =
      cmd_line->GetSwitchValuePath(kSwitchNameStoragePath);

  storage_ = test::TestTokenStorage::OnDisk(username, storage_path);
  token_getter_ = std::make_unique<test::TestOAuthTokenGetter>(storage_.get());

  base::RunLoop initialize_token_getter_loop;
  token_getter_->Initialize(initialize_token_getter_loop.QuitClosure());
  initialize_token_getter_loop.Run();

  base::RunLoop ui_loop;
  ui_task_runner_ = new AutoThreadTaskRunner(
      base::ThreadTaskRunnerHandle::Get(), ui_loop.QuitClosure());

  token_getter_->CallWithToken(base::BindOnce(
      &It2MeCliHost::StartCRDHostAndGetCode, base::Unretained(this)));

  std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier(
      net::NetworkChangeNotifier::CreateIfNeeded());
  ui_loop.Run();
}

void It2MeCliHost::PostMessageFromNativeHost(const std::string& message) {
  auto message_value = base::JSONReader::Read(message);
  if (!message_value || !message_value->is_dict()) {
    OnProtocolBroken("Message is not a dictionary");
    return;
  }

  auto* type_value = message_value->FindKeyOfType(kCRDMessageTypeKey,
                                                  base::Value::Type::STRING);
  if (!type_value) {
    OnProtocolBroken("Message without type");
    return;
  }
  std::string type = type_value->GetString();

  if (type == kCRDResponseHello) {
    OnHelloResponse();
  } else if (type == kCRDResponseConnect) {
    // Ok, just ignore.
  } else if (type == kCRDResponseDisconnect) {
    OnDisconnectResponse();
  } else if (type == kCRDStateChanged) {
    // Handle CRD host state changes
    auto* state_value =
        message_value->FindKeyOfType(kCRDStateKey, base::Value::Type::STRING);
    if (!state_value) {
      OnProtocolBroken("No state in message");
      return;
    }
    std::string state = state_value->GetString();

    if (state == kCRDStateAccessCode) {
      OnStateReceivedAccessCode(*message_value);
    } else if (state == kCRDStateRemoteConnected) {
      OnStateRemoteConnected(*message_value);
    } else if (state == kCRDStateRemoteDisconnected) {
      OnStateRemoteDisconnected();
    } else if (state == kCRDStateError || state == kCRDStateDomainError) {
      OnStateError(state, *message_value);
    } else if (state == kCRDStateStarting ||
               state == kCRDStateAccessCodeRequested) {
      // Just ignore these states.
    } else {
      LOG(WARNING) << "Unhandled state: " << state;
    }
  } else if (type == kCRDDebugLog) {
    // The It2Me host already prints the log to stdout/stderr.
  } else {
    LOG(WARNING) << "Unknown message type: " << type;
  }
}

void It2MeCliHost::CloseChannel(const std::string& error_message) {
  LOG(ERROR) << "CRD Host closed channel: " << error_message;
  command_awaiting_crd_access_code_ = false;

  ShutdownHost();
}

void It2MeCliHost::SendMessageToHost(const std::string& type,
                                     base::Value params) {
  std::string message_json;
  params.SetKey(kCRDMessageTypeKey, base::Value(type));
  base::JSONWriter::Write(params, &message_json);
  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, base::BindOnce(&It2MeCliHost::DoSendMessage,
                                weak_factory_.GetWeakPtr(), message_json));
}

void It2MeCliHost::DoSendMessage(const std::string& json) {
  if (!host_)
    return;
  host_->OnMessage(json);
}

void It2MeCliHost::OnProtocolBroken(const std::string& message) {
  LOG(ERROR) << "Error communicating with CRD Host : " << message;
  command_awaiting_crd_access_code_ = false;

  ShutdownHost();
}

void It2MeCliHost::StartCRDHostAndGetCode(OAuthTokenGetter::Status status,
                                          const std::string& user_email,
                                          const std::string& access_token) {
  DCHECK(!host_);

  // Store all parameters for future connect call.
  base::Value connect_params(base::Value::Type::DICTIONARY);

  connect_params.SetKey(kCRDConnectUserName, base::Value(user_email));
  connect_params.SetKey(kCRDConnectAuth, base::Value("oauth2:" + access_token));
  connect_params.SetKey(kCRDConnectSuppressUserDialogs, base::Value(true));
  connect_params.SetKey(kCRDConnectSuppressNotifications, base::Value(true));
  connect_params_ = std::move(connect_params);

  remote_connected_ = false;
  command_awaiting_crd_access_code_ = true;

  host_ = CreateNativeMessagingHost(ui_task_runner_);
  host_->Start(this);

  base::Value params(base::Value::Type::DICTIONARY);
  SendMessageToHost(kCRDMessageHello, std::move(params));
}

void It2MeCliHost::ShutdownHost() {
  if (!host_)
    return;
  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, base::BindOnce(&It2MeCliHost::DoShutdownHost,
                                weak_factory_.GetWeakPtr()));
}

void It2MeCliHost::DoShutdownHost() {
  host_.reset();
  ui_task_runner_.reset();
}

void It2MeCliHost::OnHelloResponse() {
  // Host is initialized, start connection.
  SendMessageToHost(kCRDMessageConnect, std::move(connect_params_));
}

void It2MeCliHost::OnDisconnectResponse() {
  // Should happen only when remoting session finished and we
  // have requested host to shut down, or when we have got second auth code
  // without receiving connection.
  DCHECK(!command_awaiting_crd_access_code_);
  DCHECK(!remote_connected_);
  ShutdownHost();
}

void It2MeCliHost::OnStateError(const std::string& error_state,
                                const base::Value& message) {
  std::string error_message;
  if (error_state == kCRDStateDomainError) {
    error_message = "CRD Error : Invalid domain";
  } else {
    auto* error_code_value =
        message.FindKeyOfType(kCRDErrorCodeKey, base::Value::Type::STRING);
    if (error_code_value)
      error_message = error_code_value->GetString();
    else
      error_message = "Unknown CRD Error";
  }
  // Notify callback if command is still running.
  if (command_awaiting_crd_access_code_) {
    command_awaiting_crd_access_code_ = false;
    LOG(ERROR) << "CRD Error state " + error_state;
  }
  // Shut down host, if any
  ShutdownHost();
}

void It2MeCliHost::OnStateRemoteConnected(const base::Value& message) {
  remote_connected_ = true;
  auto* client_value =
      message.FindKeyOfType(kCRDConnectClientKey, base::Value::Type::STRING);
  if (client_value) {
    HOST_LOG << "Remote connection by " << client_value->GetString();
  }
}

void It2MeCliHost::OnStateRemoteDisconnected() {
  // There could be a connection attempt that was not successful, we will
  // receive "disconnected" message without actually receiving "connected".
  if (!remote_connected_)
    return;
  remote_connected_ = false;
  // Remote has disconnected, time to send "disconnect" that would result
  // in shutting down the host.
  base::Value params(base::Value::Type::DICTIONARY);
  SendMessageToHost(kCRDMessageDisconnect, std::move(params));
}

void It2MeCliHost::OnStateReceivedAccessCode(const base::Value& message) {
  if (!command_awaiting_crd_access_code_) {
    if (!remote_connected_) {
      // We have already sent the access code back to the server which initiated
      // this CRD session through a remote command, and we can not send a new
      // access code. Assuming that the old access code is no longer valid, we
      // can only terminate the current CRD session.
      base::Value params(base::Value::Type::DICTIONARY);
      SendMessageToHost(kCRDMessageDisconnect, std::move(params));
    }
    return;
  }

  auto* code_value =
      message.FindKeyOfType(kCRDAccessCodeKey, base::Value::Type::STRING);
  auto* code_lifetime_value = message.FindKeyOfType(kCRDAccessCodeLifetimeKey,
                                                    base::Value::Type::INTEGER);
  if (!code_value || !code_lifetime_value) {
    OnProtocolBroken("Can not obtain access code");
    return;
  }
  command_awaiting_crd_access_code_ = false;

  // Prints the access code.
  base::TimeDelta expires_in =
      base::TimeDelta::FromSeconds(code_lifetime_value->GetInt());
  HOST_LOG << "It2Me access code is generated: " << code_value->GetString();
  HOST_LOG << "Expires at: " << (base::Time::Now() + expires_in);
}

}  // namespace remoting
