/*
 * 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.
 */

#include <unistd.h>
#include <string>

#include <android-base/file.h>
#include <android-base/test_utils.h>
#include <gtest/gtest.h>

#include "JavaGen.h"

namespace {

constexpr const char* kTestSyspropFile =
    R"(owner: Vendor
module: "com.somecompany.TestProperties"

prop {
    api_name: "test_double"
    type: Double
    prop_name: "vendor.test_double"
    scope: Internal
    access: ReadWrite
}
prop {
    api_name: "test_int"
    type: Integer
    prop_name: "vendor.test_int"
    scope: Public
    access: ReadWrite
}
prop {
    api_name: "test_string"
    type: String
    prop_name: "vendor.test.string"
    scope: Public
    access: Readonly
    legacy_prop_name: "vendor.old.string"
}
prop {
    api_name: "test_enum"
    type: Enum
    prop_name: "vendor.test.enum"
    enum_values: "a|b|c|D|e|f|G"
    scope: Internal
    access: ReadWrite
}
prop {
    api_name: "test_BOOLeaN"
    type: Boolean
    prop_name: "ro.vendor.test.b"
    scope: Public
    access: Writeonce
}
prop {
    api_name: "vendor_os_test-long"
    type: Long
    scope: Public
    access: ReadWrite
}
prop {
    api_name: "test_double_list"
    type: DoubleList
    scope: Internal
    access: ReadWrite
}
prop {
    api_name: "test_list_int"
    type: IntegerList
    scope: Public
    access: ReadWrite
}
prop {
    api_name: "test_strlist"
    type: StringList
    scope: Public
    access: ReadWrite
    deprecated: true
}
prop {
    api_name: "el"
    type: EnumList
    enum_values: "enu|mva|lue"
    scope: Internal
    access: ReadWrite
    deprecated: true
}
)";

constexpr const char* kExpectedPublicOutput =
    R"s(// Generated by the sysprop generator. DO NOT EDIT!

package com.somecompany;

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;

public final class TestProperties {
    private TestProperties () {}

    private static Boolean tryParseBoolean(String str) {
        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();
    }

    public static Optional<Integer> test_int() {
        String value = SystemProperties.get("vendor.test_int");
        return Optional.ofNullable(tryParseInteger(value));
    }

    public static void test_int(Integer value) {
        SystemProperties.set("vendor.test_int", value == null ? "" : value.toString());
    }

    public static Optional<String> test_string() {
        String value = SystemProperties.get("vendor.test.string");
        if ("".equals(value)) {
            Log.v("TestProperties", "prop vendor.test.string doesn't exist; fallback to legacy prop vendor.old.string");
            value = SystemProperties.get("vendor.old.string");
        }
        return Optional.ofNullable(tryParseString(value));
    }

    public static Optional<Boolean> test_BOOLeaN() {
        String value = SystemProperties.get("ro.vendor.test.b");
        return Optional.ofNullable(tryParseBoolean(value));
    }

    public static void test_BOOLeaN(Boolean value) {
        SystemProperties.set("ro.vendor.test.b", value == null ? "" : value.toString());
    }

    public static Optional<Long> vendor_os_test_long() {
        String value = SystemProperties.get("vendor.vendor_os_test-long");
        return Optional.ofNullable(tryParseLong(value));
    }

    public static void vendor_os_test_long(Long value) {
        SystemProperties.set("vendor.vendor_os_test-long", value == null ? "" : value.toString());
    }

    public static List<Integer> test_list_int() {
        String value = SystemProperties.get("vendor.test_list_int");
        return tryParseList(v -> tryParseInteger(v), value);
    }

    public static void test_list_int(List<Integer> value) {
        SystemProperties.set("vendor.test_list_int", value == null ? "" : formatList(value));
    }

    @Deprecated
    public static List<String> test_strlist() {
        String value = SystemProperties.get("vendor.test_strlist");
        return tryParseList(v -> tryParseString(v), value);
    }

    @Deprecated
    public static void test_strlist(List<String> value) {
        SystemProperties.set("vendor.test_strlist", value == null ? "" : formatList(value));
    }
}
)s";

constexpr const char* kExpectedInternalOutput =
    R"s(// Generated by the sysprop generator. DO NOT EDIT!

package com.somecompany;

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;

public final class TestProperties {
    private TestProperties () {}

    private static Boolean tryParseBoolean(String str) {
        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();
    }

    public static Optional<Double> test_double() {
        String value = SystemProperties.get("vendor.test_double");
        return Optional.ofNullable(tryParseDouble(value));
    }

    public static void test_double(Double value) {
        SystemProperties.set("vendor.test_double", value == null ? "" : value.toString());
    }

    public static Optional<Integer> test_int() {
        String value = SystemProperties.get("vendor.test_int");
        return Optional.ofNullable(tryParseInteger(value));
    }

    public static void test_int(Integer value) {
        SystemProperties.set("vendor.test_int", value == null ? "" : value.toString());
    }

    public static Optional<String> test_string() {
        String value = SystemProperties.get("vendor.test.string");
        if ("".equals(value)) {
            Log.v("TestProperties", "prop vendor.test.string doesn't exist; fallback to legacy prop vendor.old.string");
            value = SystemProperties.get("vendor.old.string");
        }
        return Optional.ofNullable(tryParseString(value));
    }

    public static enum test_enum_values {
        A("a"),
        B("b"),
        C("c"),
        D("D"),
        E("e"),
        F("f"),
        G("G");
        private final String propValue;
        private test_enum_values(String propValue) {
            this.propValue = propValue;
        }
        public String getPropValue() {
            return propValue;
        }
    }

    public static Optional<test_enum_values> test_enum() {
        String value = SystemProperties.get("vendor.test.enum");
        return Optional.ofNullable(tryParseEnum(test_enum_values.class, value));
    }

    public static void test_enum(test_enum_values value) {
        SystemProperties.set("vendor.test.enum", value == null ? "" : value.getPropValue());
    }

    public static Optional<Boolean> test_BOOLeaN() {
        String value = SystemProperties.get("ro.vendor.test.b");
        return Optional.ofNullable(tryParseBoolean(value));
    }

    public static void test_BOOLeaN(Boolean value) {
        SystemProperties.set("ro.vendor.test.b", value == null ? "" : value.toString());
    }

    public static Optional<Long> vendor_os_test_long() {
        String value = SystemProperties.get("vendor.vendor_os_test-long");
        return Optional.ofNullable(tryParseLong(value));
    }

    public static void vendor_os_test_long(Long value) {
        SystemProperties.set("vendor.vendor_os_test-long", value == null ? "" : value.toString());
    }

    public static List<Double> test_double_list() {
        String value = SystemProperties.get("vendor.test_double_list");
        return tryParseList(v -> tryParseDouble(v), value);
    }

    public static void test_double_list(List<Double> value) {
        SystemProperties.set("vendor.test_double_list", value == null ? "" : formatList(value));
    }

    public static List<Integer> test_list_int() {
        String value = SystemProperties.get("vendor.test_list_int");
        return tryParseList(v -> tryParseInteger(v), value);
    }

    public static void test_list_int(List<Integer> value) {
        SystemProperties.set("vendor.test_list_int", value == null ? "" : formatList(value));
    }

    @Deprecated
    public static List<String> test_strlist() {
        String value = SystemProperties.get("vendor.test_strlist");
        return tryParseList(v -> tryParseString(v), value);
    }

    @Deprecated
    public static void test_strlist(List<String> value) {
        SystemProperties.set("vendor.test_strlist", value == null ? "" : formatList(value));
    }

    public static enum el_values {
        ENU("enu"),
        MVA("mva"),
        LUE("lue");
        private final String propValue;
        private el_values(String propValue) {
            this.propValue = propValue;
        }
        public String getPropValue() {
            return propValue;
        }
    }

    @Deprecated
    public static List<el_values> el() {
        String value = SystemProperties.get("vendor.el");
        return tryParseEnumList(el_values.class, value);
    }

    @Deprecated
    public static void el(List<el_values> value) {
        SystemProperties.set("vendor.el", value == null ? "" : formatEnumList(value, el_values::getPropValue));
    }
}
)s";

}  // namespace

using namespace std::string_literals;

TEST(SyspropTest, JavaGenTest) {
  TemporaryFile temp_file;

  // strlen is optimized for constants, so don't worry about it.
  ASSERT_EQ(write(temp_file.fd, kTestSyspropFile, strlen(kTestSyspropFile)),
            strlen(kTestSyspropFile));
  close(temp_file.fd);
  temp_file.fd = -1;

  TemporaryDir temp_dir;

  std::pair<sysprop::Scope, const char*> tests[] = {
      {sysprop::Scope::Internal, kExpectedInternalOutput},
      {sysprop::Scope::Public, kExpectedPublicOutput},
  };

  for (auto [scope, expected_output] : tests) {
    ASSERT_RESULT_OK(GenerateJavaLibrary(temp_file.path, scope, temp_dir.path));

    std::string java_output_path =
        temp_dir.path + "/com/somecompany/TestProperties.java"s;

    std::string java_output;
    ASSERT_TRUE(
        android::base::ReadFileToString(java_output_path, &java_output, true));
    EXPECT_EQ(java_output, expected_output);

    unlink(java_output_path.c_str());
    rmdir((temp_dir.path + "/com/somecompany"s).c_str());
    rmdir((temp_dir.path + "/com"s).c_str());
  }
}
