/*
 * Copyright (C) 2018 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.
 */

#define LOG_TAG "sysprop_cpp_gen"

#include "CppGen.h"

#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <cerrno>
#include <filesystem>
#include <regex>
#include <string>

#include "CodeWriter.h"
#include "Common.h"
#include "sysprop.pb.h"

using android::base::Result;

namespace {

constexpr const char* kIndent = "    ";

constexpr const char* kCppHeaderIncludes =
    R"(#include <cstdint>
#include <optional>
#include <string>
#include <vector>

)";

constexpr const char* kCppSourceIncludes =
    R"(#include <cctype>
#include <cerrno>
#include <cstdio>
#include <cstring>
#include <limits>
#include <utility>

#include <strings.h>
#ifdef __BIONIC__
#include <sys/system_properties.h>
[[maybe_unused]] static bool SetProp(const char* key, const char* value) {
    return __system_property_set(key, value) == 0;
}
#else
#include <android-base/properties.h>
[[maybe_unused]] static bool SetProp(const char* key, const char* value) {
    android::base::SetProperty(key, value);
    return true;
}
#endif

#include <android-base/parseint.h>
#include <log/log.h>

)";

constexpr const char* kCppParsersAndFormatters =
    R"(template <typename T> constexpr bool is_vector = false;

template <typename T> constexpr bool is_vector<std::vector<T>> = true;

template <> [[maybe_unused]] std::optional<bool> DoParse(const char* str) {
    static constexpr const char* kYes[] = {"1", "true"};
    static constexpr const char* kNo[] = {"0", "false"};

    for (const char* yes : kYes) {
        if (strcasecmp(yes, str) == 0) return std::make_optional(true);
    }

    for (const char* no : kNo) {
        if (strcasecmp(no, str) == 0) return std::make_optional(false);
    }

    return std::nullopt;
}

template <> [[maybe_unused]] std::optional<std::int32_t> DoParse(const char* str) {
    std::int32_t ret;
    return android::base::ParseInt(str, &ret) ? std::make_optional(ret) : std::nullopt;
}

template <> [[maybe_unused]] std::optional<std::int64_t> DoParse(const char* str) {
    std::int64_t ret;
    return android::base::ParseInt(str, &ret) ? std::make_optional(ret) : std::nullopt;
}

template <> [[maybe_unused]] std::optional<double> DoParse(const char* str) {
    int old_errno = errno;
    errno = 0;
    char* end;
    double ret = std::strtod(str, &end);
    if (errno != 0) {
        return std::nullopt;
    }
    if (str == end || *end != '\0') {
        errno = EINVAL;
        return std::nullopt;
    }
    errno = old_errno;
    return std::make_optional(ret);
}

template <> [[maybe_unused]] std::optional<std::string> DoParse(const char* str) {
    return *str == '\0' ? std::nullopt : std::make_optional(str);
}

template <typename Vec> [[maybe_unused]] Vec DoParseList(const char* str) {
    Vec ret;
    if (*str == '\0') return ret;
    const char* p = str;
    for (;;) {
        const char* r = p;
        std::string value;
        while (*r != ',') {
            if (*r == '\\') ++r;
            if (*r == '\0') break;
            value += *r++;
        }
        ret.emplace_back(DoParse<typename Vec::value_type>(value.c_str()));
        if (*r == '\0') break;
        p = r + 1;
    }
    return ret;
}

template <typename T> inline T TryParse(const char* str) {
    if constexpr(is_vector<T>) {
        return DoParseList<T>(str);
    } else {
        return DoParse<T>(str);
    }
}

[[maybe_unused]] std::string FormatValue(const std::optional<std::int32_t>& value) {
    return value ? std::to_string(*value) : "";
}

[[maybe_unused]] std::string FormatValue(const std::optional<std::int64_t>& value) {
    return value ? std::to_string(*value) : "";
}

[[maybe_unused]] std::string FormatValue(const std::optional<double>& value) {
    if (!value) return "";
    char buf[1024];
    std::sprintf(buf, "%.*g", std::numeric_limits<double>::max_digits10, *value);
    return buf;
}

[[maybe_unused]] std::string FormatValue(const std::optional<bool>& value) {
    return value ? (*value ? "true" : "false") : "";
}

template <typename T>
[[maybe_unused]] std::string FormatValue(const std::vector<T>& value) {
    if (value.empty()) return "";

    std::string ret;
    bool first = true;

    for (auto&& element : value) {
        if (!first) ret += ',';
        else first = false;
        if constexpr(std::is_same_v<T, std::optional<std::string>>) {
            if (element) {
                for (char c : *element) {
                    if (c == '\\' || c == ',') ret += '\\';
                    ret += c;
                }
            }
        } else {
            ret += FormatValue(element);
        }
    }

    return ret;
}

template <typename T>
T GetProp(const char* key, const char* legacy = nullptr) {
    std::string value;
#ifdef __BIONIC__
    auto pi = __system_property_find(key);
    if (pi != nullptr) {
        __system_property_read_callback(pi, [](void* cookie, const char*, const char* value, std::uint32_t) {
            *static_cast<std::string*>(cookie) = value;
        }, &value);
    }
#else
    value = android::base::GetProperty(key, "");
#endif
    if (value.empty() && legacy) {
        ALOGD("prop %s doesn't exist; fallback to legacy prop %s", key, legacy);
        return GetProp<T>(legacy);
    }
    return TryParse<T>(value.c_str());
}

)";

const std::regex kRegexDot{"\\."};
const std::regex kRegexUnderscore{"_"};

std::string GetCppEnumName(const sysprop::Property& prop);
std::string GetCppPropTypeName(const sysprop::Property& prop);
std::string GetCppNamespace(const sysprop::Properties& props);

std::string GenerateHeader(const sysprop::Properties& props,
                           sysprop::Scope scope);
std::string GenerateSource(const sysprop::Properties& props,
                           const std::string& include_name);

std::string GetCppEnumName(const sysprop::Property& prop) {
  return ApiNameToIdentifier(prop.api_name()) + "_values";
}

std::string GetCppPropTypeName(const sysprop::Property& prop) {
  switch (prop.type()) {
    case sysprop::Boolean:
      return "std::optional<bool>";
    case sysprop::Integer:
      return "std::optional<std::int32_t>";
    case sysprop::Long:
      return "std::optional<std::int64_t>";
    case sysprop::Double:
      return "std::optional<double>";
    case sysprop::String:
      return "std::optional<std::string>";
    case sysprop::Enum:
      return "std::optional<" + GetCppEnumName(prop) + ">";
    case sysprop::BooleanList:
      return "std::vector<std::optional<bool>>";
    case sysprop::IntegerList:
      return "std::vector<std::optional<std::int32_t>>";
    case sysprop::LongList:
      return "std::vector<std::optional<std::int64_t>>";
    case sysprop::DoubleList:
      return "std::vector<std::optional<double>>";
    case sysprop::StringList:
      return "std::vector<std::optional<std::string>>";
    case sysprop::EnumList:
      return "std::vector<std::optional<" + GetCppEnumName(prop) + ">>";
    default:
      __builtin_unreachable();
  }
}

std::string GetCppNamespace(const sysprop::Properties& props) {
  return std::regex_replace(props.module(), kRegexDot, "::");
}

std::string GenerateHeader(const sysprop::Properties& props,
                           sysprop::Scope scope) {
  CodeWriter writer(kIndent);

  writer.Write("%s", kGeneratedFileFooterComments);

  writer.Write("#pragma once\n\n");
  writer.Write("%s", kCppHeaderIncludes);

  std::string cpp_namespace = GetCppNamespace(props);
  writer.Write("namespace %s {\n\n", cpp_namespace.c_str());

  bool first = true;

  for (int i = 0; i < props.prop_size(); ++i) {
    const sysprop::Property& prop = props.prop(i);

    // Scope: Internal > Public
    if (prop.scope() > scope) continue;

    if (!first) {
      writer.Write("\n");
    } else {
      first = false;
    }

    std::string prop_id = ApiNameToIdentifier(prop.api_name());
    std::string prop_type = GetCppPropTypeName(prop);

    if (prop.type() == sysprop::Enum || prop.type() == sysprop::EnumList) {
      writer.Write("enum class %s {\n", GetCppEnumName(prop).c_str());
      writer.Indent();
      for (const std::string& name :
           android::base::Split(prop.enum_values(), "|")) {
        writer.Write("%s,\n", ToUpper(name).c_str());
      }
      writer.Dedent();
      writer.Write("};\n\n");
    }

    if (prop.deprecated()) writer.Write("[[deprecated]] ");
    writer.Write("%s %s();\n", prop_type.c_str(), prop_id.c_str());
    if (prop.access() != sysprop::Readonly) {
      if (prop.deprecated()) writer.Write("[[deprecated]] ");
      writer.Write("bool %s(const %s& value);\n", prop_id.c_str(),
                   prop_type.c_str());
    }
  }

  writer.Write("\n}  // namespace %s\n", cpp_namespace.c_str());

  return writer.Code();
}

std::string GenerateSource(const sysprop::Properties& props,
                           const std::string& include_name) {
  CodeWriter writer(kIndent);
  writer.Write("%s", kGeneratedFileFooterComments);
  writer.Write("#include <%s>\n\n", include_name.c_str());
  writer.Write("%s", kCppSourceIncludes);

  std::string cpp_namespace = GetCppNamespace(props);

  writer.Write("namespace {\n\n");
  writer.Write("using namespace %s;\n\n", cpp_namespace.c_str());
  writer.Write("template <typename T> T DoParse(const char* str);\n\n");

  for (int i = 0; i < props.prop_size(); ++i) {
    const sysprop::Property& prop = props.prop(i);
    if (prop.type() != sysprop::Enum && prop.type() != sysprop::EnumList) {
      continue;
    }

    std::string prop_id = ApiNameToIdentifier(prop.api_name());
    std::string enum_name = GetCppEnumName(prop);

    writer.Write("constexpr const std::pair<const char*, %s> %s_list[] = {\n",
                 enum_name.c_str(), prop_id.c_str());
    writer.Indent();
    for (const std::string& name : ParseEnumValues(prop.enum_values())) {
      writer.Write("{\"%s\", %s::%s},\n", name.c_str(), enum_name.c_str(),
                   ToUpper(name).c_str());
    }
    writer.Dedent();
    writer.Write("};\n\n");

    writer.Write("template <>\n");
    writer.Write("std::optional<%s> DoParse(const char* str) {\n",
                 enum_name.c_str());
    writer.Indent();
    writer.Write("for (auto [name, val] : %s_list) {\n", prop_id.c_str());
    writer.Indent();
    writer.Write("if (strcmp(str, name) == 0) {\n");
    writer.Indent();
    writer.Write("return val;\n");
    writer.Dedent();
    writer.Write("}\n");
    writer.Dedent();
    writer.Write("}\n");
    writer.Write("return std::nullopt;\n");
    writer.Dedent();
    writer.Write("}\n\n");

    if (prop.access() != sysprop::Readonly) {
      writer.Write("std::string FormatValue(std::optional<%s> value) {\n",
                   enum_name.c_str());
      writer.Indent();
      writer.Write("if (!value) return \"\";\n");
      writer.Write("for (auto [name, val] : %s_list) {\n", prop_id.c_str());
      writer.Indent();
      writer.Write("if (val == *value) {\n");
      writer.Indent();
      writer.Write("return name;\n");
      writer.Dedent();
      writer.Write("}\n");
      writer.Dedent();
      writer.Write("}\n");

      writer.Write(
          "LOG_ALWAYS_FATAL(\"Invalid value %%d for property %s\", "
          "static_cast<std::int32_t>(*value));\n",
          prop.prop_name().c_str());

      writer.Write("__builtin_unreachable();\n");
      writer.Dedent();
      writer.Write("}\n\n");
    }
  }
  writer.Write("%s", kCppParsersAndFormatters);
  writer.Write("}  // namespace\n\n");

  writer.Write("namespace %s {\n\n", cpp_namespace.c_str());

  for (int i = 0; i < props.prop_size(); ++i) {
    if (i > 0) writer.Write("\n");

    const sysprop::Property& prop = props.prop(i);
    std::string prop_id = ApiNameToIdentifier(prop.api_name());
    std::string prop_type = GetCppPropTypeName(prop);
    std::string prop_name = prop.prop_name();
    std::string legacy_name = prop.legacy_prop_name();

    writer.Write("%s %s() {\n", prop_type.c_str(), prop_id.c_str());
    writer.Indent();
    if (legacy_name.empty()) {
      writer.Write("return GetProp<%s>(\"%s\");\n", prop_type.c_str(),
                   prop_name.c_str());
    } else {
      writer.Write("return GetProp<%s>(\"%s\", \"%s\");\n", prop_type.c_str(),
                   prop_name.c_str(), legacy_name.c_str());
    }
    writer.Dedent();
    writer.Write("}\n");

    if (prop.access() != sysprop::Readonly) {
      writer.Write("\nbool %s(const %s& value) {\n", prop_id.c_str(),
                   prop_type.c_str());
      writer.Indent();

      const char* format_expr = "FormatValue(value).c_str()";

      // Specialized formatters here
      if (prop.type() == sysprop::String) {
        format_expr = "value ? value->c_str() : \"\"";
      } else if (prop.integer_as_bool()) {
        if (prop.type() == sysprop::Boolean) {
          // optional<bool> -> optional<int>
          format_expr = "FormatValue(std::optional<int>(value)).c_str()";
        } else if (prop.type() == sysprop::BooleanList) {
          // vector<optional<bool>> -> vector<optional<int>>
          format_expr =
              "FormatValue(std::vector<std::optional<int>>("
              "value.begin(), value.end())).c_str()";
        }
      }

      writer.Write("return SetProp(\"%s\", %s);\n", prop.prop_name().c_str(),
                   format_expr);
      writer.Dedent();
      writer.Write("}\n");
    }
  }

  writer.Write("\n}  // namespace %s\n", cpp_namespace.c_str());

  return writer.Code();
}

}  // namespace

Result<void> GenerateCppFiles(const std::string& input_file_path,
                              const std::string& header_dir,
                              const std::string& public_header_dir,
                              const std::string& source_output_dir,
                              const std::string& include_name) {
  sysprop::Properties props;

  if (auto res = ParseProps(input_file_path); res.ok()) {
    props = std::move(*res);
  } else {
    return res.error();
  }

  std::string output_basename = android::base::Basename(input_file_path);

  for (auto&& [scope, dir] : {
           std::pair(sysprop::Internal, header_dir),
           std::pair(sysprop::Public, public_header_dir),
       }) {
    std::error_code ec;
    std::filesystem::create_directories(dir, ec);
    if (ec) {
      return Errorf("Creating directory to {} failed: {}", dir, ec.message());
    }

    std::string path = dir + "/" + output_basename + ".h";
    std::string result = GenerateHeader(props, scope);

    if (!android::base::WriteStringToFile(result, path)) {
      return ErrnoErrorf("Writing generated header to {} failed", path);
    }
  }

  std::string source_path = source_output_dir + "/" + output_basename + ".cpp";
  std::string source_result = GenerateSource(props, include_name);

  if (!android::base::WriteStringToFile(source_result, source_path)) {
    return ErrnoErrorf("Writing generated source to {} failed", source_path);
  }

  return {};
}
