/*
 * 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: System
    access: ReadWrite
}

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: System
    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: System
    access: ReadWrite
}

prop {
    api_name: "el"
    type: EnumList
    enum_values: "enu|mva|lue"
    scope: Internal
    access: ReadWrite
}
)";

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

package com.somecompany;

import android.annotation.SystemApi;

import android.os.SystemProperties;
import java.util.ArrayList;
import java.util.function.Function;
import java.util.List;
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()) {
            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 Long tryParseLong(String str) {
        try {
            return Long.valueOf(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());
        } 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<>();

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

        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 <T> String formatList(List<T> list) {
        StringJoiner joiner = new StringJoiner(",");

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

        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();
    }

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

    /** @hide */
    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));
    }

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

    /** @hide */
    @SystemApi
    public static Optional<String> test_string() {
        String value = SystemProperties.get("vendor.test.string");
        return Optional.ofNullable(tryParseString(value));
    }

    /** @hide */
    public static void test_string(String value) {
        SystemProperties.set("vendor.test.string", value == null ? "" : value.toString());
    }

    /** @hide */
    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;
        }
    }

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

    /** @hide */
    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));
    }

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

    /** @hide */
    @SystemApi
    public static Optional<Long> vendor_os_test_long() {
        String value = SystemProperties.get("vendor.vendor.os_test-long");
        return Optional.ofNullable(tryParseLong(value));
    }

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

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

    /** @hide */
    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);
    }

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

    /** @hide */
    @SystemApi
    public static List<String> test_strlist() {
        String value = SystemProperties.get("vendor.test.strlist");
        return tryParseList(v -> tryParseString(v), value);
    }

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

    /** @hide */
    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;
        }
    }

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

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

}  // 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::string err;
  ASSERT_TRUE(GenerateJavaLibrary(temp_file.path, temp_dir.path, &err));
  ASSERT_TRUE(err.empty());

  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, kExpectedJavaOutput);

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