/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "host/libs/config/fetcher_config.h"

#include <fstream>
#include <map>
#include <string>
#include <vector>

#include "android-base/logging.h"
#include "android-base/strings.h"
#include "gflags/gflags.h"
#include "json/json.h"

#include "common/libs/utils/files.h"

namespace cuttlefish {

namespace {

const char* kFlags = "flags";
const char* kCvdFiles = "cvd_files";
const char* kCvdFileSource = "source";
const char* kCvdFileBuildId = "build_id";
const char* kCvdFileBuildTarget = "build_target";

FileSource SourceStringToEnum(std::string source) {
  for (auto& c : source) {
    c = std::tolower(c);
  }
  if (source == "default_build") {
    return FileSource::DEFAULT_BUILD;
  } else if (source == "system_build") {
    return FileSource::SYSTEM_BUILD;
  } else if (source == "kernel_build") {
    return FileSource::KERNEL_BUILD;
  } else if (source == "local_file") {
    return FileSource::LOCAL_FILE;
  } else if (source == "generated") {
    return FileSource::GENERATED;
  } else {
    return FileSource::UNKNOWN_PURPOSE;
  }
}

std::string SourceEnumToString(const FileSource& source) {
  if (source == FileSource::DEFAULT_BUILD) {
    return "default_build";
  } else if (source == FileSource::SYSTEM_BUILD) {
    return "system_build";
  } else if (source == FileSource::KERNEL_BUILD) {
    return "kernel_build";
  } else if (source == FileSource::LOCAL_FILE) {
    return "local_file";
  } else if (source == FileSource::GENERATED) {
    return "generated";
  } else {
    return "unknown";
  }
}

} // namespace

CvdFile::CvdFile() {
}

CvdFile::CvdFile(const FileSource& source, const std::string& build_id,
                 const std::string& build_target, const std::string& file_path)
    : source(source), build_id(build_id), build_target(build_target), file_path(file_path) {
}

std::ostream& operator<<(std::ostream& os, const CvdFile& cvd_file) {
  os << "CvdFile(";
  os << "source = " << SourceEnumToString(cvd_file.source) << ", ";
  os << "build_id = " << cvd_file.build_id << ", ";
  os << "build_target = " << cvd_file.build_target << ", ";
  os << "file_path = " << cvd_file.file_path << ")";
  return os;
}

FetcherConfig::FetcherConfig() : dictionary_(new Json::Value()) {
}

FetcherConfig::FetcherConfig(FetcherConfig&&) = default;

FetcherConfig::~FetcherConfig() {
}

bool FetcherConfig::SaveToFile(const std::string& file) const {
  std::ofstream ofs(file);
  if (!ofs.is_open()) {
    LOG(ERROR) << "Unable to write to file " << file;
    return false;
  }
  ofs << *dictionary_;
  return !ofs.fail();
}

bool FetcherConfig::LoadFromFile(const std::string& file) {
  auto real_file_path = AbsolutePath(file);
  if (real_file_path.empty()) {
    LOG(ERROR) << "Could not get real path for file " << file;
    return false;
  }
  Json::CharReaderBuilder builder;
  std::ifstream ifs(real_file_path);
  std::string errorMessage;
  if (!Json::parseFromStream(builder, ifs, dictionary_.get(), &errorMessage)) {
    LOG(ERROR) << "Could not read config file " << file << ": " << errorMessage;
    return false;
  }
  return true;
}

void FetcherConfig::RecordFlags() {
  std::vector<gflags::CommandLineFlagInfo> all_flags;
  GetAllFlags(&all_flags);
  Json::Value flags_json(Json::arrayValue);
  for (const auto& flag : all_flags) {
    Json::Value flag_json;
    flag_json["name"] = flag.name;
    flag_json["type"] = flag.type;
    flag_json["description"] = flag.description;
    flag_json["current_value"] = flag.current_value;
    flag_json["default_value"] = flag.default_value;
    flag_json["filename"] = flag.filename;
    flag_json["has_validator_fn"] = flag.has_validator_fn;
    flag_json["is_default"] = flag.is_default;
    flags_json.append(flag_json);
  }
  (*dictionary_)[kFlags] = flags_json;
}

namespace {

CvdFile JsonToCvdFile(const std::string& file_path, const Json::Value& json) {
  CvdFile cvd_file;
  cvd_file.file_path = file_path;
  if (json.isMember(kCvdFileSource)) {
    cvd_file.source = SourceStringToEnum(json[kCvdFileSource].asString());
  } else {
    cvd_file.source = UNKNOWN_PURPOSE;
  }
  if (json.isMember(kCvdFileBuildId)) {
    cvd_file.build_id = json[kCvdFileBuildId].asString();
  }
  if (json.isMember(kCvdFileBuildTarget)) {
    cvd_file.build_target = json[kCvdFileBuildTarget].asString();
  }
  return cvd_file;
}

Json::Value CvdFileToJson(const CvdFile& cvd_file) {
  Json::Value json;
  json[kCvdFileSource] = SourceEnumToString(cvd_file.source);
  json[kCvdFileBuildId] = cvd_file.build_id;
  json[kCvdFileBuildTarget] = cvd_file.build_target;
  return json;
}

} // namespace

bool FetcherConfig::add_cvd_file(const CvdFile& file, bool override_entry) {
  if (!dictionary_->isMember(kCvdFiles)) {
    Json::Value files_json(Json::objectValue);
    (*dictionary_)[kCvdFiles] = files_json;
  }
  if ((*dictionary_)[kCvdFiles].isMember(file.file_path) && !override_entry) {
    return false;
  }
  (*dictionary_)[kCvdFiles][file.file_path] = CvdFileToJson(file);
  return true;
}

std::map<std::string, CvdFile> FetcherConfig::get_cvd_files() const {
  if (!dictionary_->isMember(kCvdFiles)) {
    return {};
  }
  std::map<std::string, CvdFile> files;
  const auto& json_files = (*dictionary_)[kCvdFiles];
  for (auto it = json_files.begin(); it != json_files.end(); it++) {
    files[it.key().asString()] = JsonToCvdFile(it.key().asString(), *it);
  }
  return files;
}

std::string FetcherConfig::FindCvdFileWithSuffix(const std::string& suffix) const {
  if (!dictionary_->isMember(kCvdFiles)) {
    return {};
  }
  const auto& json_files = (*dictionary_)[kCvdFiles];
  for (auto it = json_files.begin(); it != json_files.end(); it++) {
    const auto& file = it.key().asString();
    if (android::base::EndsWith(file, suffix)) {
      return file;
    }
  }
  LOG(DEBUG) << "Could not find file ending in " << suffix;
  return "";
}

} // namespace cuttlefish
