/*
 * 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_java_gen"

#include "JavaGen.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* kJavaFileImports =
    R"(import android.os.SystemProperties;
import android.util.Log;

import java.lang.StringBuilder;
import java.util.ArrayList;
import java.util.function.Function;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.StringJoiner;
import java.util.stream.Collectors;

)";

constexpr const char* kJavaParsersAndFormatters =
    R"s(private static Boolean tryParseBoolean(String str) {
    if (str == null) return null;
    switch (str.toLowerCase(Locale.US)) {
        case "1":
        case "true":
            return Boolean.TRUE;
        case "0":
        case "false":
            return Boolean.FALSE;
        default:
            return null;
    }
}

private static Integer tryParseInteger(String str) {
    try {
        return Integer.valueOf(str);
    } catch (NumberFormatException e) {
        return null;
    }
}

private static Integer tryParseUInt(String str) {
    try {
        return Integer.parseUnsignedInt(str);
    } catch (NumberFormatException e) {
        return null;
    }
}

private static Long tryParseLong(String str) {
    try {
        return Long.valueOf(str);
    } catch (NumberFormatException e) {
        return null;
    }
}

private static Long tryParseULong(String str) {
    try {
        return Long.parseUnsignedLong(str);
    } catch (NumberFormatException e) {
        return null;
    }
}

private static Double tryParseDouble(String str) {
    try {
        return Double.valueOf(str);
    } catch (NumberFormatException e) {
        return null;
    }
}

private static String tryParseString(String str) {
    return "".equals(str) ? null : str;
}

private static <T extends Enum<T>> T tryParseEnum(Class<T> enumType, String str) {
    try {
        return Enum.valueOf(enumType, str.toUpperCase(Locale.US));
    } catch (IllegalArgumentException e) {
        return null;
    }
}

private static <T> List<T> tryParseList(Function<String, T> elementParser, String str) {
    if ("".equals(str)) return new ArrayList<>();

    List<T> ret = new ArrayList<>();

    int p = 0;
    for (;;) {
        StringBuilder sb = new StringBuilder();
        while (p < str.length() && str.charAt(p) != ',') {
            if (str.charAt(p) == '\\') ++p;
            if (p == str.length()) break;
            sb.append(str.charAt(p++));
        }
        ret.add(elementParser.apply(sb.toString()));
        if (p == str.length()) break;
        ++p;
    }

    return ret;
}

private static <T extends Enum<T>> List<T> tryParseEnumList(Class<T> enumType, String str) {
    if ("".equals(str)) return new ArrayList<>();

    List<T> ret = new ArrayList<>();

    for (String element : str.split(",")) {
        ret.add(tryParseEnum(enumType, element));
    }

    return ret;
}

private static String escape(String str) {
    return str.replaceAll("([\\\\,])", "\\\\$1");
}

private static <T> String formatList(List<T> list) {
    StringJoiner joiner = new StringJoiner(",");

    for (T element : list) {
        joiner.add(element == null ? "" : escape(element.toString()));
    }

    return joiner.toString();
}

private static String formatUIntList(List<Integer> list) {
    StringJoiner joiner = new StringJoiner(",");

    for (Integer element : list) {
        joiner.add(element == null ? "" : escape(Integer.toUnsignedString(element)));
    }

    return joiner.toString();
}

private static String formatULongList(List<Long> list) {
    StringJoiner joiner = new StringJoiner(",");

    for (Long element : list) {
        joiner.add(element == null ? "" : escape(Long.toUnsignedString(element)));
    }

    return joiner.toString();
}

private static <T extends Enum<T>> String formatEnumList(List<T> list, Function<T, String> elementFormatter) {
    StringJoiner joiner = new StringJoiner(",");

    for (T element : list) {
        joiner.add(element == null ? "" : elementFormatter.apply(element));
    }

    return joiner.toString();
}
)s";

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

std::string GetJavaTypeName(const sysprop::Property& prop);
std::string GetJavaEnumTypeName(const sysprop::Property& prop);
std::string GetJavaPackageName(const sysprop::Properties& props);
std::string GetJavaClassName(const sysprop::Properties& props);
std::string GetParsingExpression(const sysprop::Property& prop);
std::string GetFormattingExpression(const sysprop::Property& prop);
std::string GenerateJavaClass(const sysprop::Properties& props,
                              sysprop::Scope scope);

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

std::string GetJavaTypeName(const sysprop::Property& prop) {
  switch (prop.type()) {
    case sysprop::Boolean:
      return "Boolean";
    case sysprop::Integer:
    case sysprop::UInt:
      return "Integer";
    case sysprop::Long:
    case sysprop::ULong:
      return "Long";
    case sysprop::Double:
      return "Double";
    case sysprop::String:
      return "String";
    case sysprop::Enum:
      return GetJavaEnumTypeName(prop);
    case sysprop::BooleanList:
      return "List<Boolean>";
    case sysprop::IntegerList:
    case sysprop::UIntList:
      return "List<Integer>";
    case sysprop::LongList:
    case sysprop::ULongList:
      return "List<Long>";
    case sysprop::DoubleList:
      return "List<Double>";
    case sysprop::StringList:
      return "List<String>";
    case sysprop::EnumList:
      return "List<" + GetJavaEnumTypeName(prop) + ">";
    default:
      __builtin_unreachable();
  }
}

std::string GetParsingExpression(const sysprop::Property& prop) {
  switch (prop.type()) {
    case sysprop::Boolean:
      return "Optional.ofNullable(tryParseBoolean(value))";
    case sysprop::Integer:
      return "Optional.ofNullable(tryParseInteger(value))";
    case sysprop::UInt:
      return "Optional.ofNullable(tryParseUInt(value))";
    case sysprop::Long:
      return "Optional.ofNullable(tryParseLong(value))";
    case sysprop::ULong:
      return "Optional.ofNullable(tryParseULong(value))";
    case sysprop::Double:
      return "Optional.ofNullable(tryParseDouble(value))";
    case sysprop::String:
      return "Optional.ofNullable(tryParseString(value))";
    case sysprop::Enum:
      return "Optional.ofNullable(tryParseEnum(" + GetJavaEnumTypeName(prop) +
             ".class, value))";
    case sysprop::EnumList:
      return "tryParseEnumList(" + GetJavaEnumTypeName(prop) +
             ".class, "
             "value)";
    default:
      break;
  }

  // The remaining cases are lists for types other than Enum which share the
  // same parsing function "tryParseList"
  std::string element_parser;

  switch (prop.type()) {
    case sysprop::BooleanList:
      element_parser = "v -> tryParseBoolean(v)";
      break;
    case sysprop::IntegerList:
      element_parser = "v -> tryParseInteger(v)";
      break;
    case sysprop::LongList:
      element_parser = "v -> tryParseLong(v)";
      break;
    case sysprop::DoubleList:
      element_parser = "v -> tryParseDouble(v)";
      break;
    case sysprop::StringList:
      element_parser = "v -> tryParseString(v)";
      break;
    case sysprop::UIntList:
      element_parser = "v -> tryParseUInt(v)";
      break;
    case sysprop::ULongList:
      element_parser = "v -> tryParseULong(v)";
      break;
    default:
      __builtin_unreachable();
  }

  return "tryParseList(" + element_parser + ", value)";
}

std::string GetFormattingExpression(const sysprop::Property& prop) {
  if (prop.integer_as_bool()) {
    if (prop.type() == sysprop::Boolean) {
      // Boolean -> Integer String
      return "(value ? \"1\" : \"0\")";
    } else {
      // List<Boolean> -> String directly
      return "value.stream().map("
             "x -> x == null ? \"\" : (x ? \"1\" : \"0\"))"
             ".collect(Collectors.joining(\",\"))";
    }
  }

  switch (prop.type()) {
    case sysprop::Enum:
      return "value.getPropValue()";
    case sysprop::EnumList:
      return "formatEnumList(value, " + GetJavaEnumTypeName(prop) +
             "::getPropValue)";
    case sysprop::UInt:
      return "Integer.toUnsignedString(value)";
    case sysprop::ULong:
      return "Long.toUnsignedString(value)";
    case sysprop::UIntList:
      return "formatUIntList(value)";
    case sysprop::ULongList:
      return "formatULongList(value)";
    default:
      break;
  }

  return IsListProp(prop) ? "formatList(value)" : "value.toString()";
}

std::string GetJavaPackageName(const sysprop::Properties& props) {
  const std::string& module = props.module();
  return module.substr(0, module.rfind('.'));
}

std::string GetJavaClassName(const sysprop::Properties& props) {
  const std::string& module = props.module();
  return module.substr(module.rfind('.') + 1);
}

std::string GenerateJavaClass(const sysprop::Properties& props,
                              sysprop::Scope scope) {
  std::string package_name = GetJavaPackageName(props);
  std::string class_name = GetJavaClassName(props);

  CodeWriter writer(kIndent);
  writer.Write("%s", kGeneratedFileFooterComments);
  writer.Write("package %s;\n\n", package_name.c_str());
  writer.Write("%s", kJavaFileImports);
  writer.Write("public final class %s {\n", class_name.c_str());
  writer.Indent();
  writer.Write("private %s () {}\n\n", class_name.c_str());
  writer.Write("%s", kJavaParsersAndFormatters);

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

    // skip if scope is internal and we are generating public class
    if (prop.scope() > scope) continue;

    writer.Write("\n");

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

    if (prop.type() == sysprop::Enum || prop.type() == sysprop::EnumList) {
      writer.Write("public static enum %s {\n",
                   GetJavaEnumTypeName(prop).c_str());
      writer.Indent();
      std::vector<std::string> values = ParseEnumValues(prop.enum_values());
      for (std::size_t i = 0; i < values.size(); ++i) {
        const std::string& name = values[i];
        writer.Write("%s(\"%s\")", ToUpper(name).c_str(), name.c_str());
        if (i + 1 < values.size()) {
          writer.Write(",\n");
        } else {
          writer.Write(";\n");
        }
      }
      writer.Write(
          "private final String propValue;\n"
          "private %s(String propValue) {\n",
          GetJavaEnumTypeName(prop).c_str());
      writer.Indent();
      writer.Write("this.propValue = propValue;\n");
      writer.Dedent();
      writer.Write(
          "}\n"
          "public String getPropValue() {\n");
      writer.Indent();
      writer.Write("return propValue;\n");
      writer.Dedent();
      writer.Write("}\n");
      writer.Dedent();
      writer.Write("}\n\n");
    }

    if (prop.deprecated()) {
      writer.Write("@Deprecated\n");
    }

    if (IsListProp(prop)) {
      writer.Write("public static %s %s() {\n", prop_type.c_str(),
                   prop_id.c_str());
    } else {
      writer.Write("public static Optional<%s> %s() {\n", prop_type.c_str(),
                   prop_id.c_str());
    }
    writer.Indent();
    writer.Write("String value = SystemProperties.get(\"%s\");\n",
                 prop.prop_name().c_str());
    if (!prop.legacy_prop_name().empty()) {
      // SystemProperties.get() returns "" (empty string) when the property
      // doesn't exist
      writer.Write("if (\"\".equals(value)) {\n");
      writer.Indent();
      writer.Write(
          "Log.v(\"%s\", \"prop %s doesn't exist; fallback to legacy prop "
          "%s\");\n",
          class_name.c_str(), prop.prop_name().c_str(),
          prop.legacy_prop_name().c_str());
      writer.Write("value = SystemProperties.get(\"%s\");\n",
                   prop.legacy_prop_name().c_str());
      writer.Dedent();
      writer.Write("}\n");
    }
    writer.Write("return %s;\n", GetParsingExpression(prop).c_str());
    writer.Dedent();
    writer.Write("}\n");

    if (prop.access() != sysprop::Readonly) {
      writer.Write("\n");
      if (prop.deprecated()) {
        writer.Write("@Deprecated\n");
      }
      writer.Write("public static void %s(%s value) {\n", prop_id.c_str(),
                   prop_type.c_str());
      writer.Indent();
      writer.Write("SystemProperties.set(\"%s\", value == null ? \"\" : %s);\n",
                   prop.prop_name().c_str(),
                   GetFormattingExpression(prop).c_str());
      writer.Dedent();
      writer.Write("}\n");
    }
  }

  writer.Dedent();
  writer.Write("}\n");

  return writer.Code();
}

}  // namespace

Result<void> GenerateJavaLibrary(const std::string& input_file_path,
                                 sysprop::Scope scope,
                                 const std::string& java_output_dir) {
  sysprop::Properties props;

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

  std::string java_result = GenerateJavaClass(props, scope);
  std::string package_name = GetJavaPackageName(props);
  std::string java_package_dir =
      java_output_dir + "/" + std::regex_replace(package_name, kRegexDot, "/");

  std::error_code ec;
  std::filesystem::create_directories(java_package_dir, ec);
  if (ec) {
    return Errorf("Creating directory to {} failed: {}", java_package_dir,
                  ec.message());
  }

  std::string class_name = GetJavaClassName(props);
  std::string java_output_file = java_package_dir + "/" + class_name + ".java";
  if (!android::base::WriteStringToFile(java_result, java_output_file)) {
    return ErrnoErrorf("Writing generated java class to {} failed",
                       java_output_file);
  }

  return {};
}
