/*
 * 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.nifi.processor;

import org.apache.nifi.parameter.ParameterLookup;
import org.apache.nifi.attribute.expression.language.StandardPropertyValue;
import org.apache.nifi.components.PropertyValue;
import org.apache.nifi.controller.ControllerService;
import org.apache.nifi.controller.ControllerServiceLookup;
import org.apache.nifi.controller.repository.StandardFlowFileRecord;
import org.apache.nifi.flowfile.FlowFile;
import org.junit.Test;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

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


public class TestStandardPropertyValue {

    private final ControllerServiceLookup lookup = new TestControllerServiceLookup();

    @Test
    public void testSubstituteAttributesWithOneMatchingArg() {
        final PropertyValue value = new StandardPropertyValue("Hello, ${audience}!", lookup, ParameterLookup.EMPTY);
        final Map<String, String> attributes = new HashMap<>();
        attributes.put("audience", "World");
        assertEquals("Hello, World!", value.evaluateAttributeExpressions(createFlowFile(attributes)).getValue());
    }

    @Test
    public void testMissingEndBraceEvaluatesToStringLiteral() {
        final PropertyValue value = new StandardPropertyValue("Hello, ${audience!", lookup, ParameterLookup.EMPTY);
        final Map<String, String> attributes = new HashMap<>();
        attributes.put("audience", "World");
        assertEquals("Hello, ${audience!", value.evaluateAttributeExpressions(createFlowFile(attributes)).getValue());
    }

    @Test
    public void testEscaped() {
        final PropertyValue value = new StandardPropertyValue("Hello, $${audience}!", lookup, ParameterLookup.EMPTY);
        final Map<String, String> attributes = new HashMap<>();
        attributes.put("audience", "World");
        assertEquals("Hello, ${audience}!", value.evaluateAttributeExpressions(createFlowFile(attributes)).getValue());
    }

    @Test
    public void testSubstituteAttributesWithMultipleMatchingArgs() {
        final PropertyValue value = new StandardPropertyValue("Hello, ${audience}${comma}${question}!", lookup, ParameterLookup.EMPTY);
        final Map<String, String> attributes = new HashMap<>();
        attributes.put("audience", "World");
        attributes.put("comma", ",");
        attributes.put("question", " how are you?");
        assertEquals("Hello, World, how are you?!", value.evaluateAttributeExpressions(createFlowFile(attributes)).getValue());
    }

    @Test
    public void testSubstituteAttributesWithNoMatch() {
        final PropertyValue value = new StandardPropertyValue("Hello, ${audience}${comma}${question:replaceNull('')}!", lookup, ParameterLookup.EMPTY);
        final Map<String, String> attributes = new HashMap<>();
        assertEquals("Hello, !", value.evaluateAttributeExpressions(createFlowFile(attributes)).getValue());
    }

    @Test
    public void testSubstituteAttributesRecursively() {
        final PropertyValue value = new StandardPropertyValue("Hello, ${'${a}${b}'}!", lookup, ParameterLookup.EMPTY);
        final Map<String, String> attributes = new HashMap<>();
        attributes.put("a", "b");
        attributes.put("b", "World");
        attributes.put("bWorld", "World");
        assertEquals("Hello, World!", value.evaluateAttributeExpressions(createFlowFile(attributes)).getValue());
    }

    @Test
    public void testGetValueAsIntegerAfterSubstitute() {
        final PropertyValue value = new StandardPropertyValue("1${value}", lookup, ParameterLookup.EMPTY);
        final Map<String, String> attributes = new HashMap<>();
        attributes.put("value", "39");
        assertEquals(139, value.evaluateAttributeExpressions(createFlowFile(attributes)).asInteger().intValue());
    }

    @Test(expected = NumberFormatException.class)
    public void testGetValueAsIntegerAfterSubstitutingWithNonInteger() {
        final PropertyValue value = new StandardPropertyValue("1${value}", lookup, ParameterLookup.EMPTY);
        final Map<String, String> attributes = new HashMap<>();
        attributes.put("value", "Yes");
        final PropertyValue substituted = value.evaluateAttributeExpressions(createFlowFile(attributes));
        substituted.asInteger();
    }

    @Test
    public void testFileSize() {
        final PropertyValue value = new StandardPropertyValue("${fileSize}", lookup, ParameterLookup.EMPTY);
        final FlowFile flowFile = new StandardFlowFileRecord.Builder().size(1024 * 1024L).build();
        final long val = value.evaluateAttributeExpressions(flowFile).asLong().longValue();
        assertEquals(1024 * 1024L, val);
    }

    @Test
    public void testFlowFileEntryYear() {
        final Calendar now = Calendar.getInstance();
        final int year = now.get(Calendar.YEAR);
        final PropertyValue value = new StandardPropertyValue("${entryDate:toNumber():toDate():format('yyyy')}", lookup, ParameterLookup.EMPTY);
        final FlowFile flowFile = new StandardFlowFileRecord.Builder().entryDate(now.getTimeInMillis()).build();
        final int val = value.evaluateAttributeExpressions(flowFile).asInteger().intValue();
        assertEquals(year, val);
    }

    @Test
    public void testisExpressionLanguagePresentShouldHandleNPE() {
        // Arrange
        final PropertyValue value = new StandardPropertyValue(null, lookup, ParameterLookup.EMPTY);

        // Act
        boolean elPresent = value.isExpressionLanguagePresent();

        // Assert
        assertFalse(elPresent);
    }

    private FlowFile createFlowFile(final Map<String, String> attributes) {
        return new StandardFlowFileRecord.Builder().addAttributes(attributes).build();
    }

    private static class TestControllerServiceLookup implements ControllerServiceLookup {

        private final Map<String, ControllerService> map = new HashMap<>();

        @Override
        public ControllerService getControllerService(final String serviceIdentifier) {
            return map.get(serviceIdentifier);
        }

        @Override
        public Set<String> getControllerServiceIdentifiers(final Class<? extends ControllerService> serviceType) {
            return null;
        }

        @Override
        public boolean isControllerServiceEnabled(final String serviceIdentifier) {
            return true;
        }

        @Override
        public boolean isControllerServiceEnabled(final ControllerService service) {
            return true;
        }

        @Override
        public String getControllerServiceName(final String serviceIdentifier) {
            return null;
        }

        @Override
        public boolean isControllerServiceEnabling(final String serviceIdentifier) {
            return false;
        }

    }
}
