// Copyright 2021 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 "featured/service.h"

#include <memory>
#include <string>
#include <unordered_map>
#include <utility>

#include <base/json/json_reader.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/stringprintf.h>
#include <build/build_config.h>
#include <build/buildflag.h>

#include "base/files/file.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_file.h"
#include "base/files/scoped_temp_dir.h"

namespace featured {

namespace {
constexpr char kPlatformFeaturesPath[] = "/etc/init/platform-features.json";

// JSON Helper to retrieve a string value given a string key
bool GetStringFromKey(const base::Value& obj,
                      const std::string& key,
                      std::string* value) {
  const std::string* val = obj.FindStringKey(key);
  if (!val || val->empty()) {
    return false;
  }

  *value = *val;
  return true;
}
}  // namespace

WriteFileCommand::WriteFileCommand(const std::string& file_name,
                                   const std::string& value)
    : FeatureCommand("WriteFile") {
  file_name_ = file_name;
  value_ = value;
}

bool WriteFileCommand::Execute() {
  if (!base::WriteFile(base::FilePath(file_name_), value_)) {
    PLOG(ERROR) << "Unable to write to " << file_name_;
    return false;
  }
  return true;
}

FileExistsCommand::FileExistsCommand(const std::string& file_name)
    : FeatureCommand("FileExists") {
  file_name_ = file_name;
}

bool FileExistsCommand::Execute() {
  return base::PathExists(base::FilePath(file_name_));
}

bool PlatformFeature::Execute() const {
  for (auto& cmd : exec_cmds_) {
    if (!cmd->Execute()) {
      LOG(ERROR) << "Failed to execute command: " << cmd->name();
      return false;
    }
  }
  return true;
}

bool PlatformFeature::IsSupported() const {
  for (auto& cmd : support_check_cmds_) {
    if (!cmd->Execute()) {
      return false;
    }
  }
  return true;
}

bool JsonFeatureParser::ParseFile(const base::FilePath& path,
                                  std::string* err_str) {
  std::string input;

  if (features_parsed_)
    return true;

  if (!ReadFileToString(path, &input)) {
    *err_str = "featured: Failed to read conf file: ";
    *err_str += kPlatformFeaturesPath;
    return false;
  }

  VLOG(1) << "JSON file contents: " << input;

  base::JSONReader::ValueWithError root =
      base::JSONReader::ReadAndReturnValueWithError(input);
  if (!root.value) {
    *err_str = "featured: Failed to parse conf file: ";
    *err_str += kPlatformFeaturesPath;
    return false;
  }

  if (!root.value->is_list() || root.value->GetList().size() == 0) {
    *err_str = "featured: features list should be non-zero size!";
    return false;
  }

  for (const auto& item : root.value->GetList()) {
    if (!item.is_dict()) {
      *err_str = "featured: features conf not list of dicts!";
      return false;
    }

    auto feature_obj_optional = MakeFeatureObject(item, err_str);
    if (!feature_obj_optional) {
      return false;
    }
    PlatformFeature feature_obj(std::move(*feature_obj_optional));

    auto got = feature_map_.find(feature_obj.name());
    if (got != feature_map_.end()) {
      *err_str =
          "featured: Duplicate feature name found! : " + feature_obj.name();
      return false;
    }

    feature_map_.insert(
        std::make_pair(feature_obj.name(), std::move(feature_obj)));
  }

  features_parsed_ = true;
  return true;
}

// PlatformFeature implementation (collect and execute commands).
std::optional<PlatformFeature> JsonFeatureParser::MakeFeatureObject(
    const base::Value& feature_obj, std::string* err_str) {
  std::string feat_name;
  if (!GetStringFromKey(feature_obj, "name", &feat_name)) {
    *err_str = "featured: features conf contains empty names";
    return std::nullopt;
  }

  // Commands for querying if device is supported
  const base::Value* support_cmd_list_obj =
      feature_obj.FindListKey("support_check_commands");

  std::vector<std::unique_ptr<FeatureCommand>> query_cmds;
  if (!support_cmd_list_obj) {
    // Feature is assumed to be always supported, such as a kernel parameter
    // that is on all device kernels.
    query_cmds.push_back(std::make_unique<AlwaysSupportedCommand>());
  } else {
    // A support check command was provided, add it to the feature object.
    if (!support_cmd_list_obj->is_list() ||
        support_cmd_list_obj->GetList().size() == 0) {
      *err_str = "featured: Invalid format for support_check_commands commands";
      return std::nullopt;
    }

    for (const auto& item : support_cmd_list_obj->GetList()) {
      std::string cmd_name;

      if (!GetStringFromKey(item, "name", &cmd_name)) {
        *err_str = "featured: Invalid/Empty command name in features config.";
        return std::nullopt;
      }

      if (cmd_name == "FileExists") {
        std::string file_name;

        VLOG(1) << "featured: command is FileExists";
        if (!GetStringFromKey(item, "file", &file_name)) {
          *err_str = "featured: JSON contains invalid command name";
          return std::nullopt;
        }

        query_cmds.push_back(std::make_unique<FileExistsCommand>(file_name));
      } else {
        *err_str =
            "featured: Invalid support command name in features config: ";
        *err_str += cmd_name;
        return std::nullopt;
      }
    }
  }

  // Commands to execute to enable feature
  const base::Value* cmd_list_obj = feature_obj.FindListKey("commands");
  if (!cmd_list_obj || !cmd_list_obj->is_list() ||
      cmd_list_obj->GetList().size() == 0) {
    *err_str = "featured: Failed to get commands list in feature.";
    return std::nullopt;
  }

  std::vector<std::unique_ptr<FeatureCommand>> feature_cmds;
  for (const auto& item : cmd_list_obj->GetList()) {
    std::string cmd_name;

    if (!GetStringFromKey(item, "name", &cmd_name)) {
      *err_str = "featured: Invalid command in features config.";
      return std::nullopt;
    }

    if (cmd_name == "WriteFile") {
      std::string file_name, value;

      VLOG(1) << "featured: command is WriteFile";
      if (!GetStringFromKey(item, "file", &file_name)) {
        *err_str = "featured: JSON contains invalid command name!";
        return std::nullopt;
      }

      if (!GetStringFromKey(item, "value", &value)) {
        *err_str = "featured: JSON contains invalid command value!";
        return std::nullopt;
      }
      feature_cmds.push_back(
          std::make_unique<WriteFileCommand>(file_name, value));
    } else {
      *err_str = "featured: Invalid command name in features config: ";
      *err_str += cmd_name;
      return std::nullopt;
    }
  }

  return PlatformFeature(feat_name, std::move(query_cmds),
                         std::move(feature_cmds));
}

bool DbusFeaturedService::ParseFeatureList(std::string* err_str) {
  DCHECK(err_str);

  return parser_->ParseFile(base::FilePath(kPlatformFeaturesPath), err_str);
}

bool DbusFeaturedService::GetFeatureList(std::string* csv_list,
                                         std::string* err_str) {
  DCHECK(csv_list);
  DCHECK(err_str);

  csv_list->clear();

  if (!ParseFeatureList(err_str)) {
    return false;
  }

  bool first = true;
  for (const auto& it : *(parser_->GetFeatureMap())) {
    if (!first)
      csv_list->append(",");
    else
      first = false;

    csv_list->append(it.first);
  }

  return true;
}

bool DbusFeaturedService::PlatformFeatureEnable(const std::string& name,
                                                std::string* err_str) {
  DCHECK(err_str);

  if (!ParseFeatureList(err_str)) {
    return false;
  }

  auto feature = parser_->GetFeatureMap()->find(name);
  if (feature == parser_->GetFeatureMap()->end()) {
    *err_str = "featured: Feature not found in features config!";
    return false;
  }

  const PlatformFeature& feature_obj = feature->second;
  if (!feature_obj.IsSupported()) {
    *err_str = "featured: device does not support feature " + name;
    return false;
  }

  if (!feature_obj.Execute()) {
    *err_str = "featured: Tried but failed to enable feature " + name;
    return false;
  }

  /* On success, return the feature name to featured for context. */
  *err_str = name;
  VLOG(1) << "featured: PlatformFeatureEnable: Feature " << name << " enabled";
  return true;
}

void DbusFeaturedService::PlatformFeatureEnableWrap(
    dbus::MethodCall* method_call,
    dbus::ExportedObject::ResponseSender sender) {
  std::string out, err_str;
  bool ret;

  dbus::MessageReader reader(method_call);
  std::string name;
  if (!reader.PopString(&name)) {
    out.append("error: missing string argument");
    ret = false;
  } else if (!PlatformFeatureEnable(name, &err_str)) {
    // If failure, assign the output string as the error message
    out.append("error: ");
    out.append(err_str);
    ret = false;
  } else {
    ret = true;
  }

  std::unique_ptr<dbus::Response> response =
      dbus::Response::FromMethodCall(method_call);
  dbus::MessageWriter writer(response.get());

  writer.AppendBool(ret);
  writer.AppendString(out);

  std::move(sender).Run(std::move(response));
}

void DbusFeaturedService::PlatformFeatureList(
    dbus::MethodCall* method_call,
    dbus::ExportedObject::ResponseSender sender) {
  std::string out, csv, err_str;
  bool ret;

  // If failure, assign the output string as the error message
  if (!GetFeatureList(&csv, &err_str)) {
    out.append("error: ");
    out.append(err_str);
    ret = false;
  } else {
    VLOG(1) << "featured: PlatformFeatureList: " << csv;
    out = csv;
    ret = true;
  }

  std::unique_ptr<dbus::Response> response =
      dbus::Response::FromMethodCall(method_call);
  dbus::MessageWriter writer(response.get());

  writer.AppendBool(ret);
  writer.AppendString(out);

  std::move(sender).Run(std::move(response));
}

bool DbusFeaturedService::Start(dbus::Bus* bus,
                                std::shared_ptr<DbusFeaturedService> ptr) {
  if (!bus || !bus->Connect()) {
    LOG(ERROR) << "Failed to connect to DBus";
    return false;
  }

  dbus::ObjectPath path(featured::kFeaturedServicePath);
  dbus::ExportedObject* object = bus->GetExportedObject(path);
  if (!object) {
    LOG(ERROR) << "Failed to get exported object at " << path.value();
    return false;
  }

  if (!object->ExportMethodAndBlock(
          featured::kFeaturedServiceName, featured::kPlatformFeatureList,
          base::BindRepeating(&DbusFeaturedService::PlatformFeatureList,
                              ptr))) {
    bus->UnregisterExportedObject(path);
    LOG(ERROR) << "Failed to export method " << featured::kPlatformFeatureList;
    return false;
  }

  if (!object->ExportMethodAndBlock(
          featured::kFeaturedServiceName, featured::kPlatformFeatureEnable,
          base::BindRepeating(&DbusFeaturedService::PlatformFeatureEnableWrap,
                              ptr))) {
    bus->UnregisterExportedObject(path);
    LOG(ERROR) << "Failed to export method "
               << featured::kPlatformFeatureEnable;
    return false;
  }

  if (!bus->RequestOwnershipAndBlock(featured::kFeaturedServiceName,
                                     dbus::Bus::REQUIRE_PRIMARY)) {
    bus->UnregisterExportedObject(path);
    LOG(ERROR) << "Failed to get ownership of "
               << featured::kFeaturedServiceName;
    return false;
  }

  return true;
}

}  // namespace featured
