// Copyright 2017 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.

#include "authpolicy/authpolicy_flags.h"

#include <algorithm>
#include <memory>

#include <base/base64.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/json/json_reader.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_split.h>
#include <base/values.h>

#include "authpolicy/log_colors.h"

namespace authpolicy {
namespace {

// Size for alignment of Dump() output.
const size_t kAlignSize = 30;

// Gets a string with kAlignSize - strlen(str) spaces (at least 1).
std::string Align(const char* str) {
  return std::string(kAlignSize - std::min(kAlignSize - 1, strlen(str)), ' ');
}

// Removes the value with the key |name| from |dict|, checks |type| and returns
// the value if the type matches. Prints an error message otherwise.
std::unique_ptr<base::Value> GetValueOfType(base::DictionaryValue* dict,
                                            const char* name,
                                            base::Value::Type type) {
  std::unique_ptr<base::Value> value;
  if (!dict->Remove(name, &value))
    return nullptr;
  if (!value->IsType(type)) {
    LOG(ERROR) << name << " must be a "
               << base::Value::GetTypeName(value->type());
    return nullptr;
  }
  return value;
}

// Metadata used for defining a bool-type flag.
class BoolFlag {
 public:
  using Setter = void (protos::DebugFlags::*)(bool);
  using Getter = bool (protos::DebugFlags::*)() const;
  constexpr BoolFlag(const char* name, Setter setter, Getter getter)
      : name_(name), setter_(setter), getter_(getter) {}

  // Remove the value with key |name_| from |dict| and puts it into |flags|.
  void Handle(protos::DebugFlags* flags, base::DictionaryValue* dict) const {
    std::unique_ptr<base::Value> value =
        GetValueOfType(dict, name_, base::Value::Type::BOOLEAN);
    if (value) {
      bool bool_value = false;
      CHECK(value->GetAsBoolean(&bool_value));
      (flags->*setter_)(bool_value);
    }
  }

  // Prints out the value of this flag.
  void Log(const protos::DebugFlags* flags) const {
    LOG(INFO) << kColorFlags << "  " << name_ << Align(name_)
              << ((flags->*getter_)() ? "ON" : "OFF") << kColorReset;
  }

 private:
  const char* name_;
  Setter setter_;
  Getter getter_;
};

// Metadata used for defining a string-type flag.
class StringFlag {
 public:
  using Setter = void (protos::DebugFlags::*)(const std::string&);
  using Getter = const std::string& (protos::DebugFlags::*)() const;
  constexpr StringFlag(const char* name, Setter setter, Getter getter)
      : name_(name), setter_(setter), getter_(getter) {}

  // Remove the value with key |name_| from |dict| and puts it into |flags|.
  void Handle(protos::DebugFlags* flags, base::DictionaryValue* dict) const {
    std::unique_ptr<base::Value> value =
        GetValueOfType(dict, name_, base::Value::Type::STRING);
    if (value) {
      std::string string_value;
      CHECK(value->GetAsString(&string_value));
      (flags->*setter_)(string_value);
    }
  }

  // Prints out the value of this flag.
  void Log(const protos::DebugFlags* flags) const {
    LOG(INFO) << kColorFlags << "  " << name_ << Align(name_)
              << (flags->*getter_)() << kColorReset;
  }

 private:
  const char* name_;
  Setter setter_;
  Getter getter_;
};

#define DEFINE_FLAG(name) \
  { #name, &protos::DebugFlags::set_##name, &protos::DebugFlags::name }

// Bool flags.
constexpr BoolFlag kBoolFlags[] = {
    DEFINE_FLAG(disable_seccomp),
    DEFINE_FLAG(log_seccomp),
    DEFINE_FLAG(trace_krb5),
    DEFINE_FLAG(log_policy_values),
    DEFINE_FLAG(log_commands),
    DEFINE_FLAG(log_command_output),
    DEFINE_FLAG(log_command_output_on_error),
    DEFINE_FLAG(log_gpo),
    DEFINE_FLAG(disable_anonymizer),
    DEFINE_FLAG(log_status),
    DEFINE_FLAG(log_caches),
};

// String flags.
constexpr StringFlag kStringFlags[] = {
    DEFINE_FLAG(net_log_level),
};

#undef DEFINE_FLAG

}  // namespace

// static
std::string SerializeFlags(const protos::DebugFlags& flags) {
  std::string proto_blob, proto_encoded;
  CHECK(flags.SerializeToString(&proto_blob));
  base::Base64Encode(proto_blob, &proto_encoded);
  return proto_encoded;
}

// static
bool DeserializeFlags(const std::string& proto_encoded,
                      protos::DebugFlags* flags) {
  std::string proto_blob;
  return base::Base64Decode(proto_encoded, &proto_blob) &&
         flags->ParseFromString(proto_blob);
}

void AuthPolicyFlags::SetDefaults(DefaultLevel default_level) {
  // Wipe all flags.
  flags_ = protos::DebugFlags();

  // Set defaults depending on level.
  switch (default_level) {
    case kQuiet:
      break;
    case kTaciturn:
      flags_.set_log_policy_values(true);
      flags_.set_log_commands(true);
      flags_.set_log_gpo(true);
      flags_.set_log_status(true);
      flags_.set_log_caches(true);
      break;
    case kChatty:
      flags_.set_log_policy_values(true);
      flags_.set_log_commands(true);
      flags_.set_log_command_output_on_error(true);
      flags_.set_log_gpo(true);
      flags_.set_log_status(true);
      flags_.set_log_caches(true);
      flags_.set_net_log_level("3");
      break;
    case kVerbose:
      flags_.set_log_policy_values(true);
      flags_.set_log_commands(true);
      flags_.set_log_command_output_on_error(true);
      flags_.set_log_gpo(true);
      flags_.set_log_status(true);
      flags_.set_log_caches(true);
      flags_.set_net_log_level("10");
      // TODO(ljusten): Consider removing this once stabilized. Note that
      // uprev'ing a dependency of Samba might introduce seccomp failures,
      // though! See https://crbug.com/752944.
      flags_.set_log_seccomp(true);
      flags_.set_trace_krb5(true);
      break;
  }
}

bool AuthPolicyFlags::LoadFromJsonFile(const base::FilePath& path) {
  std::string flags_json;
  if (!base::ReadFileToString(path, &flags_json))
    return false;
  LoadFromJsonString(flags_json);
  return true;
}

void AuthPolicyFlags::LoadFromJsonString(const std::string& flags_json) {
  std::string error_message;
  std::unique_ptr<base::Value> root = base::JSONReader::ReadAndReturnError(
      flags_json, base::JSON_ALLOW_TRAILING_COMMAS,
      nullptr /* error_code_out */, &error_message);
  base::DictionaryValue* dict = nullptr;
  if (!root || !root->GetAsDictionary(&dict)) {
    LOG(ERROR) << "Fail to parse flags: "
               << (error_message.empty() ? "Invalid JSON" : error_message);
    return;
  }

  // Check bool flags.
  for (const BoolFlag& bool_flag : kBoolFlags)
    bool_flag.Handle(&flags_, dict);

  // Check string flags.
  for (const StringFlag& string_flag : kStringFlags)
    string_flag.Handle(&flags_, dict);

  // Print warnings for other parameters.
  for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance())
    LOG(WARNING) << "Unhandled flag " << it.key();
}

void AuthPolicyFlags::Dump() const {
  LOG(INFO) << kColorFlags << "Debug flags:" << kColorReset;
  for (const BoolFlag& flag : kBoolFlags)
    flag.Log(&flags_);
  for (const StringFlag& flag : kStringFlags)
    flag.Log(&flags_);
}

}  // namespace authpolicy
