// Copyright (c) 2012 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.

// This is the Chaps client. It sends calls to the Chaps daemon via D-Bus.

#include <stdio.h>
#include <stdlib.h>

#include <string>
#include <vector>

#include <base/command_line.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <base/time/time.h>
#include <chromeos/syslog_logging.h>

#include "chaps/chaps_proxy.h"
#include "chaps/chaps_utility.h"
#include "chaps/isolate.h"
#include "chaps/token_manager_client.h"

using base::FilePath;
using chaps::IsolateCredentialManager;
using chromeos::SecureBlob;
using std::string;
using std::vector;

namespace {

void PrintHelp() {
  printf("Usage: chaps_client COMMAND [ARGUMENTS]\n");
  printf("Commands:\n");
  printf("  --ping : Checks that the Chaps daemon is available.\n");
  printf("  --load --path=<path> --auth=<auth> [--label=<label>]"
         " : Loads the token at the given path.\n");
  printf("  --unload --path=<path> : Unloads the token at the given path.\n");
  printf("  --change_auth --path=<path> --auth=<old_auth> --new_auth=<new_auth>"
         " : Changes authorization data for the token at the given path.\n");
  printf("  --set_log_level=<level> : Sets the chapsd logging level.\n"
         "    Levels: \n      2 - Errors Only\n      1 - Warnings and Errors\n"
         "      0 - Normal\n     -1 - Verbose (Logs PKCS #11 calls.)\n"
         "     -2 - More Verbose (Logs PKCS #11 calls and arguments.)\n");
  printf("  --list : Lists all loaded token paths.\n");
}

void Ping() {
  chaps::ChapsProxyImpl proxy;
  if (!proxy.Init())
    exit(-1);
  vector<uint64_t> slot_list;
  uint32_t result = proxy.GetSlotList(
      IsolateCredentialManager::GetDefaultIsolateCredential(),
      true,
      &slot_list);
  if (result != 0) {
    LOG(ERROR) << "Chaps is available but failed to provide a token list.";
    exit(-1);
  }
  LOG(INFO) << "Chaps is available with " << slot_list.size() << " token(s).";
}

// Loads a token given a path and auth data.
void LoadToken(const string& path, const string& auth, const string& label) {
  chaps::TokenManagerClient client;
  int slot_id = -1;
  client.LoadToken(IsolateCredentialManager::GetDefaultIsolateCredential(),
                   FilePath(path),
                   SecureBlob(chaps::ConvertStringToByteBuffer(auth.data()),
                                                               auth.length()),
                   label,
                   &slot_id);
  LOG(INFO) << "LoadToken: " << path << " - slot = " << slot_id;
}

// Unloads a token given a path.
void UnloadToken(const string& path) {
  chaps::TokenManagerClient client;
  client.UnloadToken(IsolateCredentialManager::GetDefaultIsolateCredential(),
                     FilePath(path));
  LOG(INFO) << "Sent Event: Logout: " << path;
}

// Changes authorization data for a token at the given path.
void ChangeAuthData(const string& path,
                    const string& auth_old,
                    const string& auth_new) {
  chaps::TokenManagerClient client;
  client.ChangeTokenAuthData(
      FilePath(path),
      SecureBlob(chaps::ConvertStringToByteBuffer(auth_old.data()),
                 auth_old.length()),
      SecureBlob(chaps::ConvertStringToByteBuffer(auth_new.data()),
                 auth_new.length()));
  LOG(INFO) << "Sent Event: Change Authorization Data: " << path;
}

// Sets the logging level.
void SetLogLevel(int level) {
  chaps::ChapsProxyImpl proxy;
  if (!proxy.Init())
    exit(-1);
  proxy.SetLogLevel(level);
}

void ListTokens() {
  chaps::ChapsProxyImpl proxy;
  if (!proxy.Init())
    exit(-1);
  vector<uint64_t> slot_list;
  uint32_t result = proxy.GetSlotList(
      IsolateCredentialManager::GetDefaultIsolateCredential(),
      true,
      &slot_list);
  if (result != 0)
    exit(-1);
  chaps::TokenManagerClient client;
  for (size_t i = 0; i < slot_list.size(); ++i) {
    int slot = slot_list[i];
    FilePath path;
    if (client.GetTokenPath(
        IsolateCredentialManager::GetDefaultIsolateCredential(),
        slot,
        &path)) {
      LOG(INFO) << "Slot " << slot << ": " << path.value();
    } else {
      LOG(INFO) << "Slot " << slot << ": Empty";
    }
  }
}

}  // namespace

int main(int argc, char** argv) {
  CommandLine::Init(argc, argv);
  CommandLine* cl = CommandLine::ForCurrentProcess();
  chromeos::InitLog(chromeos::kLogToSyslog | chromeos::kLogToStderr);

  bool ping = cl->HasSwitch("ping");
  bool load = (cl->HasSwitch("load") &&
               cl->HasSwitch("path") &&
               cl->HasSwitch("auth"));
  bool unload = cl->HasSwitch("unload") && cl->HasSwitch("path");
  bool change_auth = (cl->HasSwitch("change_auth") &&
                      cl->HasSwitch("path") &&
                      cl->HasSwitch("auth") &&
                      cl->HasSwitch("new_auth"));
  bool set_log_level = cl->HasSwitch("set_log_level");
  bool list = cl->HasSwitch("list");
  if (ping + load + unload + change_auth + set_log_level + list != 1) {
    PrintHelp();
    exit(-1);
  }
  if (ping) {
    Ping();
  } else if (load) {
    string label = "Default Token";
    if (cl->HasSwitch("label"))
      label = cl->GetSwitchValueASCII("label");
    LoadToken(cl->GetSwitchValueASCII("path"),
              cl->GetSwitchValueASCII("auth"),
              label);
  } else if (change_auth) {
    ChangeAuthData(cl->GetSwitchValueASCII("path"),
                   cl->GetSwitchValueASCII("auth"),
                   cl->GetSwitchValueASCII("new_auth"));
  } else if (unload) {
    UnloadToken(cl->GetSwitchValueASCII("path"));
  } else if (set_log_level) {
    int level = 0;
    if (!base::StringToInt(cl->GetSwitchValueASCII("set_log_level"), &level)) {
      LOG(ERROR) << "Invalid argument.";
      exit(-1);
    }
    SetLogLevel(level);
  } else if (list) {
    ListTokens();
  }
  return 0;
}
