/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */
package org.apache.sling.feature.extension.apiregions.api.config.validation;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.sling.feature.extension.apiregions.api.config.Mode;
import org.apache.sling.feature.extension.apiregions.api.config.Option;
import org.apache.sling.feature.extension.apiregions.api.config.PlaceholderPolicy;
import org.apache.sling.feature.extension.apiregions.api.config.PropertyDescription;
import org.apache.sling.feature.extension.apiregions.api.config.PropertyType;
import org.apache.sling.feature.extension.apiregions.api.config.Range;
import org.junit.Test;

public class PropertyValidatorTest {
    
    private final PropertyValidator validator = new PropertyValidator();
    
    /**
     * Helper method to validate an error based on the validation mode
     */
    private void validateError(final PropertyDescription prop, final Object value) {
        validateError(prop, value, 1);
    }
    
    /**
     * Helper method to validate an error based on the validation mode
     */
    private void validateError(final PropertyDescription prop, final Object value, final int errors) {
        PropertyValidationResult result;

        // error - strict mode 
        result = validator.validate(value, prop, Mode.STRICT);
        assertEquals(errors, result.getErrors().size());
        assertFalse(result.isValid());
        assertFalse(result.isSkipped());

        // error - mode lenient
        result = validator.validate(value, prop, Mode.LENIENT);
        assertEquals(errors, result.getWarnings().size());
        assertTrue(result.isValid());
        assertFalse(result.isSkipped());

        // error - mode silent
        result = validator.validate(value, prop, Mode.SILENT);
        assertTrue(result.getWarnings().isEmpty());
        assertTrue(result.isValid());
        assertFalse(result.isSkipped());

        // error - mode definitive
        result = validator.validate(value, prop, Mode.DEFINITIVE);
        assertEquals(errors, result.getWarnings().size());
        assertTrue(result.isValid());
        assertFalse(result.isSkipped());
        assertTrue(result.isUseDefaultValue());
        assertEquals(result.getDefaultValue(), prop.getDefaultValue());

        // error - mode silent definitive 
        result = validator.validate(value, prop, Mode.SILENT_DEFINITIVE);
        assertTrue(result.getWarnings().isEmpty());
        assertTrue(result.isValid());
        assertFalse(result.isSkipped());
        assertTrue(result.isUseDefaultValue());
        assertEquals(result.getDefaultValue(), prop.getDefaultValue());
    }

    /**
     * Helper method to validate that a value is valid and not skipped
     */
    private void validateValid(final PropertyDescription prop, final Object value) {
        final PropertyValidationResult result = validator.validate(value, prop);
        assertTrue(result.isValid());
        assertFalse(result.isSkipped());
        assertTrue(result.getErrors().isEmpty());
        assertFalse(result.isUseDefaultValue());
        assertNull(result.getDefaultValue());
    }

    @Test public void testValidateWithNull() {
        final PropertyDescription prop = new PropertyDescription();

        // prop not required - no error
        validateValid(prop, null);

        // prop required - error
        prop.setRequired(true);
        validateError(prop, null);
    }

    @Test public void testValidateBoolean() {
        final PropertyDescription prop = new PropertyDescription();
        prop.setType(PropertyType.BOOLEAN);

        validateValid(prop, Boolean.TRUE);
        validateValid(prop, Boolean.FALSE);
        validateValid(prop, "TRUE");
        validateValid(prop, "FALSE");

        validateError(prop, "yes");
        validateError(prop, 1);
    }

    @Test public void testValidateByte() {
        final PropertyDescription prop = new PropertyDescription();
        prop.setType(PropertyType.BYTE);

        validateValid(prop, (byte)1);
        validateValid(prop, "1");
        validateValid(prop, 1);

        validateError(prop, "yes");
    }

    @Test public void testValidateShort() {
        final PropertyDescription prop = new PropertyDescription();
        prop.setType(PropertyType.SHORT);

        validateValid(prop, (short)1);
        validateValid(prop, "1");
        validateValid(prop, 1);

        validateError(prop, "yes");
    }

    @Test public void testValidateInteger() {
        final PropertyDescription prop = new PropertyDescription();
        prop.setType(PropertyType.INTEGER);

        validateValid(prop, "1");
        validateValid(prop, 1);

        validateError(prop, "yes");
    }

    @Test public void testValidateLong() {
        final PropertyDescription prop = new PropertyDescription();
        prop.setType(PropertyType.LONG);

        validateValid(prop, 1L);
        validateValid(prop, "1");
        validateValid(prop, 1);

        validateError(prop, "yes");
    }

    @Test public void testValidateFloat() {
        final PropertyDescription prop = new PropertyDescription();
        prop.setType(PropertyType.FLOAT);

        validateValid(prop, 1.1);
        validateValid(prop, "1.1");
        validateValid(prop, 1);

        validateError(prop, "yes");
    }

    @Test public void testValidateDouble() {
        final PropertyDescription prop = new PropertyDescription();
        prop.setType(PropertyType.DOUBLE);

        validateValid(prop, 1.1d);
        validateValid(prop, "1.1");
        validateValid(prop, 1);

        validateError(prop, "yes");
    }

    @Test public void testValidateChar() {
        final PropertyDescription prop = new PropertyDescription();
        prop.setType(PropertyType.CHARACTER);

        validateValid(prop, 'x');
        validateValid(prop, "y");

        validateError(prop, "yes");
    }

    @Test public void testValidateUrl() {
        final PropertyDescription prop = new PropertyDescription();
        prop.setType(PropertyType.URL);

        validateValid(prop, "https://sling.apache.org/documentation");

        validateError(prop, "hello world");
    }

    @Test public void testValidateEmail() {
        final PropertyDescription prop = new PropertyDescription();
        prop.setType(PropertyType.EMAIL);

        validateValid(prop, "a@b.com");

        validateError(prop, "hello world");
    }

    @Test public void testValidatePassword() {
        final PropertyDescription prop = new PropertyDescription();
        prop.setType(PropertyType.PASSWORD);

        validateValid(prop, null);
        validateValid(prop, "$[secret:dbpassword]");

        validateError(prop, "secret");
    }

    @Test public void testValidatePath() {
        final PropertyDescription prop = new PropertyDescription();
        prop.setType(PropertyType.PATH);

        validateValid(prop, "/a/b/c");

        validateError(prop, "hello world");
    }
    
    @Test public void testValidateString() {
        final PropertyDescription desc = new PropertyDescription();

        validateValid(desc, "hello world");
        validateValid(desc, "$[prop:KEY]");

        // skip if required
        desc.setRequired(true);
        PropertyValidationResult result = validator.validate("$[prop:KEY]", desc);
        assertTrue(result.isValid());
        assertTrue(result.isSkipped());
        desc.setRequired(false);

        // skip if options
        desc.setOptions(Collections.singletonList(new Option()));
        result = validator.validate("$[prop:KEY]", desc);
        assertTrue(result.isValid());
        assertTrue(result.isSkipped());
        desc.setOptions(null);

        // skip if regexp
        desc.setRegex(".*");        
        result = validator.validate("$[prop:KEY]", desc);
        assertTrue(result.isValid());
        assertTrue(result.isSkipped());
        desc.setRegex(null);

        // empty string - not required
        validateValid(desc, "");

        // empty string - required
        desc.setRequired(true);
        validateError(desc, "");
        desc.setRequired(false);
    }

    @Test public void testValidateRange() {
        final PropertyDescription description = new PropertyDescription();
        description.setType(PropertyType.INTEGER);
         
        // no range set
        validateValid(description, 2);

        // empty range set
        description.setRange(new Range());
        validateValid(description, 2);

        // min set
        description.getRange().setMin(5);
        validateValid(description, 5);
        validateValid(description, 6);

        validateError(description, 4);

        validateValid(description, 5.0);
        validateValid(description, 6.0);

        validateError(description, 4.0);

        // max set
        description.getRange().setMax(6);
        validateValid(description, 5);
        validateValid(description, 6);

        validateError(description, 7);

        validateValid(description, 5.0);
        validateValid(description, 6.0);

        validateError(description, 7.0);
    }   
    
    @Test public void testValidateRegex() {
        final PropertyDescription prop = new PropertyDescription();

        // no regex
        validateValid(prop, "hello world");
        validateValid(prop, "world");

        // regex
        prop.setRegex("h(.*)");
        validateValid(prop, "hello world");

        validateError(prop, "world");

        // apply default
        prop.setDefaultValue("hello world");
        validateError(prop, "world");
    }

    @Test public void testValidateOptions() {
        final PropertyDescription prop = new PropertyDescription();

        // no options
        validateValid(prop, "foo");
        validateValid(prop, "bar");

        // options - with foo
        final List<Option> options = new ArrayList<>();
        final Option o1 = new Option();
        o1.setValue("foo");
        final Option o2 = new Option();
        o2.setValue("7");
        options.add(o1);
        options.add(o2);
        prop.setOptions(options);

        validateValid(prop, "foo");
        validateError(prop, "bar");
        validateValid(prop, 7);
    }
    
    @Test public void testValidateList() {
        final PropertyDescription prop = new PropertyDescription();

        final List<Object> values = new ArrayList<>();
        values.add("a");
        values.add("b");
        values.add("c");

        // default cardinality - no excludes/includes
        validateError(prop, values);

        // cardinality 3 - no excludes/includes
        prop.setCardinality(3);
        validateValid(prop, values);

        values.add("d");
        validateError(prop, values);

        // excludes
        prop.setExcludes(new String[] {"d", "e"});
        validateError(prop, values, 2);

        values.remove("d");
        validateValid(prop, values);

        // includes
        prop.setIncludes(new String[] {"b"});
        validateValid(prop, values);

        prop.setIncludes(new String[] {"x"});
        validateError(prop, values);

        values.add("x");
        values.remove("a");
        validateValid(prop, values);
    }

    @Test public void testValidateArray() {
        final PropertyDescription prop = new PropertyDescription();

        String[] values = new String[] {"a", "b", "c"};

        // default cardinality - no excludes/includes
        validateError(prop, values);

        // cardinality 3 - no excludes/includes
        prop.setCardinality(3);
        validateValid(prop, values);

        values = new String[] {"a", "b", "c", "d"};
        validateError(prop, values);

        // excludes
        prop.setExcludes(new String[] {"d", "e"});
        validateError(prop, values, 2);

        values = new String[] {"a", "b", "c"};
        validateValid(prop, values);

        // includes
        prop.setIncludes(new String[] {"b"});
        validateValid(prop, values);

        prop.setIncludes(new String[] {"x"});
        validateError(prop, values);

        values = new String[] {"b", "c", "x"};
        validateValid(prop, values);
    }

    @Test public void testDeprecation() {
        final PropertyDescription prop = new PropertyDescription();
        prop.setDeprecated("This is deprecated");

        final PropertyValidationResult result = validator.validate("foo", prop);
        assertTrue(result.isValid());
        assertEquals(1, result.getWarnings().size());
        assertEquals("This is deprecated", result.getWarnings().get(0));
    }


    @Test public void testEnforceOnAndSinceInMsg() {
        final PropertyDescription prop = new PropertyDescription();
        prop.setDeprecated("Deprecated message");
        prop.setEnforceOn("1970-04-01");
        prop.setSince("1970-01-01");

        final PropertyValidationResult result = validator.validate("foo", prop);
        assertTrue(result.isValid());
        assertEquals(1, result.getWarnings().size());
        assertEquals("Deprecated message. Since : 1970-01-01. Enforced on : 1970-04-01", result.getWarnings().get(0));
    }

    @Test public void testPlaceholdersString() {
        final PropertyDescription desc = new PropertyDescription();
        desc.setType(PropertyType.PATH);

        PropertyValidationResult result = null;

        result = validator.validate("$[env:variable]", desc);
        assertTrue(result.isValid());
        assertTrue(result.isSkipped());

        result = validator.validate("$[prop:variable]", desc);
        assertTrue(result.isValid());
        assertTrue(result.isSkipped());

        result = validator.validate("$[secret:variable]", desc);
        assertTrue(result.isValid());
        assertTrue(result.isSkipped());
    }

    @Test public void testPlaceholdersNumber() {
        final PropertyDescription desc = new PropertyDescription();
        desc.setType(PropertyType.INTEGER);

        PropertyValidationResult result = null;

        result = validator.validate("$[env:variable]", desc);
        assertTrue(result.isValid());
        assertTrue(result.isSkipped());

        result = validator.validate("$[prop:variable]", desc);
        assertTrue(result.isValid());
        assertTrue(result.isSkipped());

        result = validator.validate("$[secret:variable]", desc);
        assertTrue(result.isValid());
        assertTrue(result.isSkipped());
    }

    @Test public void testPlaceholdersArray() {
        final PropertyDescription desc = new PropertyDescription();
        desc.setType(PropertyType.INTEGER);
        desc.setCardinality(-1);

        PropertyValidationResult result = null;

        result = validator.validate(new Object[] {5, "$[env:variable]"}, desc);
        assertTrue(result.isValid());
        assertTrue(result.isSkipped());

        result = validator.validate(new Object[] {"hello", "$[env:variable]"}, desc);
        assertFalse(result.isValid());
        assertTrue(result.isSkipped());
    }

    @Test public void testPlaceholderPolicyRequire() {
        final PropertyDescription desc = new PropertyDescription();
        desc.setPlaceholderPolicy(PlaceholderPolicy.REQUIRE);

        PropertyValidationResult result = null;

        result = validator.validate("$[env:variable]", desc);
        assertTrue(result.isValid());
        assertFalse(result.isSkipped());

        result = validator.validate("hello", desc);
        assertFalse(result.isValid());
        assertFalse(result.isSkipped());
    }

    @Test public void testPlaceholderPolicyDeny() {
        final PropertyDescription desc = new PropertyDescription();
        desc.setPlaceholderPolicy(PlaceholderPolicy.DENY);

        PropertyValidationResult result = null;

        result = validator.validate("$[env:variable]", desc);
        assertFalse(result.isValid());
        assertFalse(result.isSkipped());

        result = validator.validate("hello", desc);
        assertTrue(result.isValid());
        assertFalse(result.isSkipped());
    }

    @Test
    public void testPropertyDescRegex() {
        final PropertyDescription desc = new PropertyDescription();
        desc.setPlaceholderPolicy(PlaceholderPolicy.ALLOW);
        desc.setPlaceholderRegex("^\\w+ [^ ]+$");
        PropertyValidationResult result = validator.validate("local $[env:AEM_EXTERNALIZER_LOCAL;default=http://localhost:4502]", desc);
        assertTrue(result.isValid());
        assertFalse(result.isSkipped());

        result = validator.validate("author $[env:AEM_EXTERNALIZER_LOCAL;default=http://localhost:4502] http://abc.def.com:9091", desc);
        assertFalse(result.isValid());
        assertFalse(result.isSkipped());

        result = validator.validate("local http://abc.ghi.com:9091", desc);
        assertTrue(result.isValid());
        assertFalse(result.isSkipped());
    }

    @Test
    public void testLiveValidation() {
        assertFalse(this.validator.isLiveValues());

        try {
            this.validator.setLiveValues(true);

            final PropertyDescription desc = new PropertyDescription();
            desc.setPlaceholderPolicy(PlaceholderPolicy.DENY);
    
            PropertyValidationResult result = null;
    
            result = validator.validate("$[env:variable]", desc);
            assertTrue(result.isValid());
            assertFalse(result.isSkipped());
    
            result = validator.validate("hello", desc);
            assertTrue(result.isValid());
            assertFalse(result.isSkipped());

        } finally {
            this.validator.setLiveValues(false);
        }
    }
}
