// Copyright 2018 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 "policy_utils/policy_tool.h"

#include <base/strings/string_util.h>
#include <base/values.h>

namespace {
using base::CommandLine;
using base::CompareCaseInsensitiveASCII;
using base::Value;
using policy_utils::PolicyWriter;

// The command that is being executed.
enum class Command { CMD_CLEAR, CMD_SET, CMD_UNKNOWN };

// Individual policies that this tool can handle.
constexpr char kPolicyDeviceAllowBluetooth[] = "DeviceAllowBlueTooth";
constexpr char kShowHomeButton[] = "ShowHomeButton";
constexpr char kBookmarkBarEnabled[] = "BookmarkBarEnabled";

// The same policies, bundled up in a list.
const policy_utils::PolicyTool::PolicyList known_policies = {
    kBookmarkBarEnabled, kPolicyDeviceAllowBluetooth, kShowHomeButton};

// Compare two strings for equality ignoring case.
bool IsEqualNoCase(const std::string& a, const std::string& b) {
  return CompareCaseInsensitiveASCII(a, b) == 0;
}

// Returns whether the policy, identified by its name, is supported.
bool VerifyPolicyName(const std::string& policy_name) {
  for (const std::string& policy : known_policies) {
    if (IsEqualNoCase(policy, policy_name))
      return true;
  }
  return false;
}

// Parse and return the command from the cmd-line arguments. Returns
// Command::CMD_UNKNOWN if the command string is missing or not recognized.
Command GetCommandFromArgs(const CommandLine::StringVector& args) {
  if (args.size() < 1)
    return Command::CMD_UNKNOWN;

  const std::string& cmd = args[0];
  if (IsEqualNoCase(cmd, "set"))
    return Command::CMD_SET;
  else if (IsEqualNoCase(cmd, "clear"))
    return Command::CMD_CLEAR;

  LOG(ERROR) << "Not a valid command: " << cmd;
  return Command::CMD_UNKNOWN;
}

// Parse and return a boolean value from the cmd-line arguments. Returns a null
// Value if the cmd-line value argument is missing or not a boolean.
Value GetBoolValueFromArgs(const CommandLine::StringVector& args) {
  if (args.size() >= 3) {
    const std::string& value = args[2];
    if (IsEqualNoCase(value, "true"))
      return Value(true);
    else if (IsEqualNoCase(value, "false"))
      return Value(false);

    LOG(ERROR) << "Not a valid boolean value: " << value;
    return Value();
  }

  return Value();
}

// Parse and return the value that is being set for the given policy. Returns
// a null Value if the set-value is missing or is not not the right type for
// the given policy.
Value GetValueForSetCommand(const std::string& policy,
                            const CommandLine::StringVector& args) {
  if (IsEqualNoCase(policy, kPolicyDeviceAllowBluetooth) ||
      IsEqualNoCase(policy, kShowHomeButton) ||
      IsEqualNoCase(policy, kBookmarkBarEnabled)) {
    return GetBoolValueFromArgs(args);
  }

  return Value();
}

// Handle command |cmd| for the given policy, taking any required value from
// the args list. Returns 0 in case of success or an error code otherwise.
bool HandleCommandForPolicy(Command cmd,
                            const std::string& policy,
                            const CommandLine::StringVector& args,
                            const PolicyWriter& writer) {
  DCHECK_NE(cmd, Command::CMD_UNKNOWN);

  if (!VerifyPolicyName(policy)) {
    LOG(ERROR) << "Not a valid policy name: " << policy;
    return false;
  }

  // If this is a 'set' command, parse the value to set from the args.
  Value set_value;
  if (cmd == Command::CMD_SET) {
    set_value = GetValueForSetCommand(policy, args);
    if (set_value.type() == Value::Type::NONE) {
      LOG(ERROR) << "No value or invalid value specified";
      return false;
    }
  }

  bool result = false;
  if (IsEqualNoCase(policy, kPolicyDeviceAllowBluetooth)) {
    if (cmd == Command::CMD_SET)
      result = writer.SetDeviceAllowBluetooth(set_value.GetBool());
    else
      result = writer.ClearDeviceAllowBluetooth();
  } else if (IsEqualNoCase(policy, kShowHomeButton)) {
    if (cmd == Command::CMD_SET)
      result = writer.SetShowHomeButton(set_value.GetBool());
    else
      result = writer.ClearShowHomeButton();
  } else if (IsEqualNoCase(policy, kBookmarkBarEnabled)) {
    if (cmd == Command::CMD_SET)
      result = writer.SetBookmarkBarEnabled(set_value.GetBool());
    else
      result = writer.ClearBookmarkBarEnabled();
  }

  if (!result) {
    LOG(ERROR) << "Could not write policy to file.\n"
                  "You may need to run policy with sudo. "
                  "You may also need to make your rootfs writeable.";
  }

  return result;
}

}  // namespace

namespace policy_utils {

using base::CommandLine;

constexpr char PolicyTool::kChromePolicyDirPath[];
constexpr char PolicyTool::kChromiumPolicyDirPath[];

// PolicyTool::PolicyTool() : writer_(kChromePolicyDirPath) {}

PolicyTool::PolicyTool(const std::string& policy_dir_path)
    : writer_(policy_dir_path) {}

bool PolicyTool::DoCommand(const CommandLine::StringVector& args) const {
  // Args must have at least one command and one policy name.
  if (args.size() < 2)
    return false;

  Command cmd = GetCommandFromArgs(args);
  if (cmd == Command::CMD_UNKNOWN)
    return false;

  const std::string& policy = args[1];
  return HandleCommandForPolicy(cmd, policy, args, writer_);
}

const PolicyTool::PolicyList& PolicyTool::get_policies() {
  return known_policies;
}

}  // namespace policy_utils
