/**
 * Copyright (C) 2006-2018 Talend Inc. - www.talend.com
 * <p>
 * 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
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * 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.
 */
package org.talend.sdk.component.server.service;

import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonList;
import static java.util.stream.Collectors.toList;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.util.List;
import java.util.Locale;
import java.util.Objects;

import javax.inject.Inject;

import org.junit.jupiter.api.Test;
import org.talend.sdk.component.runtime.manager.ParameterMeta;
import org.talend.sdk.component.server.front.model.SimplePropertyDefinition;
import org.talend.sdk.component.server.test.meecrowave.MonoMeecrowaveConfig;

import lombok.Data;

@MonoMeecrowaveConfig
class PropertiesServiceTest {

    @Inject
    private PropertiesService propertiesService;

    @Test
    void buildProperties() {
        final String[] i18nPackages = { Config.class.getPackage().getName() };

        final ParameterMeta host = new ParameterMeta(null, Config.class, ParameterMeta.Type.STRING,
                "configuration.host", "host", i18nPackages, emptyList(), null, emptyMap());
        final ParameterMeta port = new ParameterMeta(null, Config.class, ParameterMeta.Type.NUMBER,
                "configuration.port", "port", i18nPackages, emptyList(), null, emptyMap());
        final ParameterMeta username = new ParameterMeta(null, Config.class, ParameterMeta.Type.STRING,
                "configuration.username", "username", i18nPackages, emptyList(), null, emptyMap());
        final ParameterMeta password = new ParameterMeta(null, Config.class, ParameterMeta.Type.STRING,
                "configuration.password", "password", i18nPackages, emptyList(), null, emptyMap());
        final ParameterMeta config = new ParameterMeta(null, Config.class, ParameterMeta.Type.OBJECT, "configuration",
                "configuration", i18nPackages, asList(host, port, username, password), null, emptyMap());

        final List<SimplePropertyDefinition> props = propertiesService
                .buildProperties(singletonList(config), getClass().getClassLoader(), Locale.getDefault(), null)
                .collect(toList());

        assertEquals(5, props.size());
        assertEquals("Configuration", props.get(0).getDisplayName());
        assertEquals("Server Host Name", props.get(1).getDisplayName());
        assertEquals("Password", props.get(2).getDisplayName());
        assertEquals("Server Port", props.get(3).getDisplayName());
        assertEquals("User Name", props.get(4).getDisplayName());
    }

    @Test // the class BaseConfig don't contains attribute
    void validateProp() {
        assertThrows(IllegalArgumentException.class, () -> {
            ParameterMeta attribute = new ParameterMeta(null, BadConfig.class, ParameterMeta.Type.STRING,
                    "configuration.attribute", "attribute", null, emptyList(), null, emptyMap());

            ParameterMeta config = new ParameterMeta(null, Config.class, ParameterMeta.Type.OBJECT, "configuration",
                    "configuration", null, singletonList(attribute), null, emptyMap());

            propertiesService
                    .buildProperties(singletonList(config), getClass().getClassLoader(), Locale.ROOT, null)
                    .forEach(Objects::nonNull);
        });
    }

    @Data
    public static class Config {

        private String host;

        private int port;

        private String username;

        private String password;

    }

    @Data
    public static class BadConfig {
        // no attribute
    }

}

@@ -1204,37 +1204,174 @@
 ent.
-runtime.manager.ParameterMeta
+api.configuration.Option;%0Aimport org.talend.sdk.component.runtime.manager.ParameterMeta;%0Aimport org.talend.sdk.component.runtime.manager.reflect.ParameterModelService
 ;%0Aim
@@ -1609,16 +1609,16 @@
 @Inject%0A
-
     priv
@@ -1655,24 +1655,627 @@
 esService;%0A%0A
+    @Test%0A    void booleanDefault() throws NoSuchMethodException %7B%0A        final List%3CSimplePropertyDefinition%3E props = propertiesService%0A                .buildProperties(%0A                        new ParameterModelService().buildParameterMetas(%0A                                getClass().getDeclaredMethod(%22boolWrapper%22, BoolWrapper.class), null),%0A                        Thread.currentThread().getContextClassLoader(), Locale.ROOT, null)%0A                .collect(toList());%0A        assertEquals(%22true%22, props.stream().filter(p -%3E p.getName().equals(%22val%22)).findFirst().get().getDefaultValue());%0A    %7D%0A%0A
     @Test%0A  
@@ -4761,32 +4761,229 @@
      %7D);%0A    %7D%0A%0A
+    private static void boolWrapper(final BoolWrapper wrapper) %7B%0A        // no-op%0A    %7D%0A%0A    @Data%0A    public static class BoolWrapper %7B%0A%0A        @Option%0A        private boolean val = true;%0A    %7D%0A%0A
     @Data%0A    pu

test for boolean default value