// 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_writer.h"

#include <vector>

#include <base/files/file_util.h>
#include <base/json/json_writer.h>
#include <base/values.h>

namespace {

// Property name and corresponding file name for policies.
const char kPolicyDeviceAllowBluetooth[] = "DeviceAllowBluetooth";
const char kPolicyDeviceAllowBluetoothFileName[] =
    "device_allow_bluetooth.json";

const char kPolicyShowHomeButton[] = "ShowHomeButton";
const char kPolicyShowHomeButtonFileName[] = "show_home_bbuton.json";

const char kPolicyBookmarkBarEnabled[] = "BookmarkBarEnabled";
const char kPolicyBookmarkBarEnabledFileName[] = "bookmark_bar_enabled.json";

// Create all non-existent directories in path |full_path. Each directory is
// created with permission 0755. Return whether successful.
bool CreateDirectories(const base::FilePath& full_path) {
  std::vector<base::FilePath> subpaths;

  // Collect a list of all parent directories.
  base::FilePath last_path = full_path;
  subpaths.push_back(full_path);
  for (base::FilePath path = full_path.DirName();
       path.value() != last_path.value(); path = path.DirName()) {
    subpaths.push_back(path);
    last_path = path;
  }

  // Iterate through the parents and create the missing ones.
  for (std::vector<base::FilePath>::reverse_iterator i = subpaths.rbegin();
       i != subpaths.rend(); ++i) {
    if (!base::DirectoryExists(*i) && mkdir(i->value().c_str(), 0755) != 0) {
      return false;
    }
  }
  return true;
}

// Converts the given policy to a JSON string and writes it to file
// <dir_path>/<file_name>. Returns whether successul.
bool WritePolicyToFile(const base::Value& policy,
                       const base::FilePath& dir_path,
                       const char* file_name) {
  if (!file_name) {
    return false;
  }

  if (!CreateDirectories(dir_path))
    return false;

  std::string json_string;
  base::JSONWriter::Write(policy, &json_string);

  base::FilePath file_path = dir_path.Append(file_name);
  return base::WriteFile(file_path, json_string.data(), json_string.length()) ==
         json_string.length();
}

// Deletes the policy file <dir_path>/<file_name> if it exists. Returns whether
// successful.
bool DeletePolicyFile(const base::FilePath& dir_path, const char* file_name) {
  if (!file_name) {
    return false;
  }
  return base::DeleteFile(dir_path.Append(file_name), false);
}

}  // anonymous namespace

namespace policy_utils {

PolicyWriter::PolicyWriter(const std::string& dest_dir_path)
    : dest_dir_path_(dest_dir_path) {}

PolicyWriter::~PolicyWriter() {}

bool PolicyWriter::SetDeviceAllowBluetooth(bool is_allowed) const {
  base::Value policy(base::Value::Type::DICTIONARY);
  policy.SetBoolKey(kPolicyDeviceAllowBluetooth, is_allowed);
  return WritePolicyToFile(policy, dest_dir_path_,
                           kPolicyDeviceAllowBluetoothFileName);
}

bool PolicyWriter::SetShowHomeButton(bool show) const {
  base::Value policy(base::Value::Type::DICTIONARY);
  policy.SetBoolKey(kPolicyShowHomeButton, show);
  return WritePolicyToFile(policy, dest_dir_path_,
                           kPolicyShowHomeButtonFileName);
}

bool PolicyWriter::SetBookmarkBarEnabled(bool is_enabled) const {
  base::Value policy(base::Value::Type::DICTIONARY);
  policy.SetBoolKey(kPolicyBookmarkBarEnabled, is_enabled);
  return WritePolicyToFile(policy, dest_dir_path_,
                           kPolicyBookmarkBarEnabledFileName);
}

bool PolicyWriter::ClearDeviceAllowBluetooth() const {
  return DeletePolicyFile(dest_dir_path_, kPolicyDeviceAllowBluetoothFileName);
}

bool PolicyWriter::ClearShowHomeButton() const {
  return DeletePolicyFile(dest_dir_path_, kPolicyShowHomeButtonFileName);
}

bool PolicyWriter::ClearBookmarkBarEnabled() const {
  return DeletePolicyFile(dest_dir_path_, kPolicyBookmarkBarEnabledFileName);
}
}  // namespace policy_utils
