/*
 * 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.qpid.systest.disttest.endtoend;

import static org.apache.qpid.disttest.AbstractRunner.JNDI_CONFIG_PROP;
import static org.apache.qpid.disttest.ControllerRunner.HILL_CLIMB;
import static org.apache.qpid.disttest.ControllerRunner.HILL_CLIMBER_CONSUMPTION_TO_PRODUCTION_RATIO_SUCCESS_THRESHOLD;
import static org.apache.qpid.disttest.ControllerRunner.HILL_CLIMBER_MAX_NUMBER_OF_RUNS;
import static org.apache.qpid.disttest.ControllerRunner.HILL_CLIMBER_MINIMUM_DELTA;
import static org.apache.qpid.disttest.ControllerRunner.HILL_CLIMBER_PRODUCTION_TO_TARGET_RATIO_SUCCESS_THRESHOLD;
import static org.apache.qpid.disttest.ControllerRunner.HILL_CLIMBER_START_TARGET_RATE;
import static org.apache.qpid.disttest.ControllerRunner.OUTPUT_DIR_PROP;
import static org.apache.qpid.disttest.ControllerRunner.TEST_CONFIG_PROP;
import static org.apache.qpid.tests.http.HttpTestBase.DEFAULT_BROKER_CONFIG;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeThat;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import org.apache.qpid.disttest.ControllerRunner;
import org.apache.qpid.disttest.DistributedTestException;
import org.apache.qpid.disttest.controller.config.QueueConfig;
import org.apache.qpid.disttest.jms.QpidQueueCreatorFactory;
import org.apache.qpid.disttest.jms.QpidRestAPIQueueCreator;
import org.apache.qpid.disttest.message.ParticipantAttribute;
import org.apache.qpid.disttest.results.aggregation.TestResultAggregator;
import org.apache.qpid.server.model.Protocol;
import org.apache.qpid.tests.http.HttpTestBase;
import org.apache.qpid.tests.utils.BrokerAdmin;
import org.apache.qpid.tests.utils.ConfigItem;
import org.apache.qpid.test.utils.TestFileUtils;


@ConfigItem(name = "qpid.initialConfigurationLocation", value = DEFAULT_BROKER_CONFIG )
public class EndToEndTest extends HttpTestBase
{
    private static final String TEST_CONFIG_ITERATIONS = "/org/apache/qpid/systest/disttest/endtoend/iterations.json";
    private static final String TEST_CONFIG_MANYPARTICIPANTS = "/org/apache/qpid/systest/disttest/endtoend/manyparticipants.json";
    private static final String TEST_CONFIG_HILLCLIMBING = "/org/apache/qpid/systest/disttest/endtoend/hillclimbing.js";
    private static final String TEST_CONFIG_ERROR = "/org/apache/qpid/systest/disttest/endtoend/error.json";

    private static final int NUMBER_OF_HEADERS = 1;
    private static final int NUMBER_OF_SUMMARIES = 3;

    private File _outputDir;
    private File _jndiConfigFile;

    @Before
    public void setUp() throws Exception
    {
        System.setProperty("perftests.manangement-url", String.format("http://localhost:%d", getBrokerAdmin().getBrokerAddress(
                BrokerAdmin.PortType.HTTP).getPort()));
        System.setProperty("perftests.broker-virtualhostnode", getVirtualHost());
        System.setProperty("perftests.broker-virtualhost", getVirtualHost());
        System.setProperty(QpidQueueCreatorFactory.QUEUE_CREATOR_CLASS_NAME_SYSTEM_PROPERTY, QpidRestAPIQueueCreator.class.getName());
        _outputDir = createTemporaryOutputDirectory();
        assumeThat("Output dir must not exist", _outputDir.isDirectory(), is(equalTo(true)));
        _jndiConfigFile = getJNDIPropertiesFile();
        QpidRestAPIQueueCreator queueCreator = new QpidRestAPIQueueCreator();
        QueueConfig queueConfig = new QueueConfig("controllerqueue", true, Collections.<String, Object>emptyMap());
        queueCreator.createQueues(null, null, Collections.<QueueConfig>singletonList(queueConfig));
    }

    @After
    public void tearDown()
    {
        try
        {
            if (_outputDir != null && _outputDir.exists())
            {
                TestFileUtils.delete(_outputDir, true);
            }
            if (_jndiConfigFile != null)
            {
                TestFileUtils.delete(_jndiConfigFile, true);
            }
        }
        finally
        {
            System.clearProperty("perftests.manangement-url");
            System.clearProperty("perftests.broker-virtualhostnode");
            System.clearProperty("perftests.broker-virtualhost");
            System.clearProperty(QpidQueueCreatorFactory.QUEUE_CREATOR_CLASS_NAME_SYSTEM_PROPERTY);
        }
    }

    @Test
    public void testIterations() throws Exception
    {
        Map<String, String> arguments = new HashMap<>();
        arguments.put(TEST_CONFIG_PROP, getTestConfigurationPath(TEST_CONFIG_ITERATIONS));
        arguments.put(JNDI_CONFIG_PROP, _jndiConfigFile.getAbsolutePath());
        arguments.put(OUTPUT_DIR_PROP, _outputDir.getAbsolutePath());
        arguments.put(HILL_CLIMB, "false");

        runController(arguments);
        checkXmlFile(arguments);
        String[] csvLines = getCsvResults(arguments);

        int numberOfParticipants = 2;
        int numberOfIterations = 2;
        int dataRowsPerIteration = numberOfParticipants + NUMBER_OF_SUMMARIES;

        int numberOfExpectedRows = NUMBER_OF_HEADERS + dataRowsPerIteration * numberOfIterations;
        assertThat("Unexpected number of lines in CSV", csvLines.length, is(equalTo(numberOfExpectedRows)));

        final String testName = "Iterations";
        assertDataRowsForIterationArePresent(csvLines, testName, 0, dataRowsPerIteration);
        assertDataRowsForIterationArePresent(csvLines, testName, 1, dataRowsPerIteration);

        assertDataRowHasCorrectTestAndClientName(testName, "", TestResultAggregator.ALL_PARTICIPANTS_NAME, csvLines[4 + dataRowsPerIteration]);
    }

    @Test
    public void testManyParticipants() throws Exception
    {
        Map<String, String> arguments = new HashMap<>();
        arguments.put(TEST_CONFIG_PROP, getTestConfigurationPath(TEST_CONFIG_MANYPARTICIPANTS));
        arguments.put(JNDI_CONFIG_PROP, _jndiConfigFile.getAbsolutePath());
        arguments.put(OUTPUT_DIR_PROP, _outputDir.getAbsolutePath());
        arguments.put(HILL_CLIMB, "false");

        runController(arguments);
        checkXmlFile(arguments);
        String[] csvLines = getCsvResults(arguments);

        int numberOfParticipants = 4;
        int dataRowsPerIteration = numberOfParticipants + NUMBER_OF_SUMMARIES;

        int numberOfExpectedRows = NUMBER_OF_HEADERS + dataRowsPerIteration;
        assertThat("Unexpected number of lines in CSV", csvLines.length, is(equalTo(numberOfExpectedRows)));

        int actualMessagesSent = 0;
        int reportedTotalMessagesSent = 0;
        int actualMessagesReceived = 0;
        int reportedTotalMessagesReceived = 0;

        for(String csvLine : Arrays.copyOfRange(csvLines, 1, csvLines.length))
        {
            String[] cells = splitCsvCells(csvLine);

            final String participantName = cells[ParticipantAttribute.PARTICIPANT_NAME.ordinal()];
            final int numberOfMessages = Integer.valueOf(cells[ParticipantAttribute.NUMBER_OF_MESSAGES_PROCESSED.ordinal()]);
            if (participantName.equals(TestResultAggregator.ALL_PARTICIPANTS_NAME))
            {
                // ignore
            }
            else if (participantName.equals(TestResultAggregator.ALL_PRODUCER_PARTICIPANTS_NAME))
            {
                reportedTotalMessagesSent = numberOfMessages;
            }
            else if (participantName.equals(TestResultAggregator.ALL_CONSUMER_PARTICIPANTS_NAME))
            {
                reportedTotalMessagesReceived = numberOfMessages;
            }
            else if (participantName.contains("Producer"))
            {
                actualMessagesSent += numberOfMessages;
            }
            else if (participantName.contains("Consumer"))
            {
                actualMessagesReceived += numberOfMessages;
            }
        }

        assertThat("Reported total messages sent does not match total sent by producers",
                     actualMessagesSent, is(equalTo(reportedTotalMessagesSent)));
        assertThat("Reported total messages received does not match total received by consumers",
                     actualMessagesReceived, is(equalTo(reportedTotalMessagesReceived)));

    }

    @Test
    public void testHillClimbing() throws Exception
    {
        Map<String, String> arguments = new HashMap<>();
        arguments.put(TEST_CONFIG_PROP, getTestConfigurationPath(TEST_CONFIG_HILLCLIMBING));
        arguments.put(JNDI_CONFIG_PROP, _jndiConfigFile.getAbsolutePath());
        arguments.put(OUTPUT_DIR_PROP, _outputDir.getAbsolutePath());
        arguments.put(HILL_CLIMB, "true");

        // Change default performance test settings to have it executed more quickly.
        // We are not interested in an accurate repeatable value in this test.
        arguments.put(HILL_CLIMBER_START_TARGET_RATE, "131073");
        arguments.put(HILL_CLIMBER_MINIMUM_DELTA, "64000");
        arguments.put(HILL_CLIMBER_MAX_NUMBER_OF_RUNS, "1");
        arguments.put(HILL_CLIMBER_PRODUCTION_TO_TARGET_RATIO_SUCCESS_THRESHOLD, "0.01");
        arguments.put(HILL_CLIMBER_CONSUMPTION_TO_PRODUCTION_RATIO_SUCCESS_THRESHOLD, "0.01");

        runController(arguments);
        checkXmlFile(arguments);
        String[] csvLines = getCsvResults(arguments);

        int numberOfParticipants = 2;

        int numberOfExpectedRows = NUMBER_OF_HEADERS + numberOfParticipants + NUMBER_OF_SUMMARIES;
        assertThat("Unexpected number of lines in CSV", csvLines.length, is(equalTo(numberOfExpectedRows)));

        final String testName = "HillClimbing";
        assertDataRowHasCorrectTestAndClientName(testName, "producingClient", "Producer1", csvLines[1]);
        assertDataRowHasCorrectTestAndClientName(testName, "consumingClient", "Consumer1", csvLines[3]);

        assertDataRowHasCorrectTestAndClientName(testName, "", TestResultAggregator.ALL_PARTICIPANTS_NAME, csvLines[4]);
        assertDataRowHasCorrectTestAndClientName(testName, "", TestResultAggregator.ALL_CONSUMER_PARTICIPANTS_NAME, csvLines[2]);
        assertDataRowHasCorrectTestAndClientName(testName,
                                                 "",
                                                 TestResultAggregator.ALL_PRODUCER_PARTICIPANTS_NAME,
                                                 csvLines[5]);

        assertDataRowHasThroughputValues(csvLines[4]);

    }

    @Test
    public void testTestScriptCausesError() throws Exception
    {
        Map<String, String> arguments = new HashMap<>();
        arguments.put(TEST_CONFIG_PROP, getTestConfigurationPath(TEST_CONFIG_ERROR));
        arguments.put(JNDI_CONFIG_PROP, _jndiConfigFile.getAbsolutePath());
        arguments.put(OUTPUT_DIR_PROP, _outputDir.getAbsolutePath());

        try
        {
            runController(arguments);
            fail("Exception not thrown");
        }
        catch (DistributedTestException e)
        {
            // PASS
        }
    }

    public String getTestConfigurationPath(String resource) throws URISyntaxException
    {
        URL url = getClass().getResource(resource);
        assertThat(String.format("Configuration at '%s' is not found", resource), url, is(notNullValue()));
        return new File(url.toURI()).getAbsolutePath();
    }


    private void runController(Map<String, String> args) throws Exception
    {
        String[] argsAsArray = new String[args.size()];
        int i = 0;
        for(Map.Entry<String, String> entry : args.entrySet())
        {
            argsAsArray[i++] = entry.getKey() + "=" + entry.getValue();
        }

        ControllerRunner runner = new ControllerRunner();
        runner.parseArgumentsIntoConfig(argsAsArray);
        runner.runController();
    }

    private String[] getCsvResults(final Map<String, String> args) throws IOException
    {
        String testConfig = args.get(TEST_CONFIG_PROP);
        String expectedCsvFilename = buildOutputFilename(testConfig, ".csv");

        File expectedCsvOutputFile = new File(_outputDir, expectedCsvFilename);
        assertThat("CSV output file must exist", expectedCsvOutputFile.exists(), is(equalTo(true)));
        final String csvContents = new String(Files.readAllBytes(expectedCsvOutputFile.toPath()));
        return csvContents.split("\n");
    }

    private void checkXmlFile(final Map<String, String> args)
    {
        String testConfig = args.get(TEST_CONFIG_PROP);
        String expectedXmlFilename = buildOutputFilename(testConfig, ".xml");

        File expectedXmlOutputFile = new File(_outputDir, expectedXmlFilename);
        assertThat("XML output file must exist", expectedXmlOutputFile.exists(), is(equalTo(true)));
    }

    private String buildOutputFilename(final String testConfig, final String extension)
    {
        String filename = Paths.get(testConfig).getFileName().toString();
        return filename.replaceAll("\\.[^.]*$", extension);
    }

    private void assertDataRowsForIterationArePresent(String[] csvLines, String testName, int iterationNumber, int expectedCount)
    {
        String itrAsString = String.valueOf(iterationNumber);

        int actualCount = 0;
        for(String csvLine : csvLines)
        {
            String[] cells = splitCsvCells(csvLine);

            if (testName.equals(cells[ParticipantAttribute.TEST_NAME.ordinal()])
                && itrAsString.equals(cells[ParticipantAttribute.ITERATION_NUMBER.ordinal()]))
            {
                actualCount++;
            }
        }

        assertThat(String.format("Unexpected number of data rows for test name %s iteration number %d",
                                 testName,
                                 iterationNumber), actualCount, is(equalTo(expectedCount)));
    }

    private void assertDataRowHasThroughputValues(String csvLine)
    {
        String[] cells = splitCsvCells(csvLine);

        double throughput = Double.valueOf(cells[ParticipantAttribute.THROUGHPUT.ordinal()]);
        int messageThroughput = Integer.valueOf(cells[ParticipantAttribute.MESSAGE_THROUGHPUT.ordinal()]);
        assertThat("Throughput in line " + csvLine + " is not greater than zero : " + throughput,
                   throughput > 0,
                   is(equalTo(true)));
        assertThat("Message throughput in line " + csvLine + " is not greater than zero : " + messageThroughput,
                   messageThroughput > 0,
                   is(equalTo(true)));
    }

    private void assertDataRowHasCorrectTestAndClientName(String testName,
                                                          String clientName,
                                                          String participantName,
                                                          String csvLine)
    {
        String[] cells = splitCsvCells(csvLine);

        // All attributes become cells in the CSV, so this will be true
        assertThat("Unexpected number of cells in CSV line " + csvLine,
                   cells.length,
                   is(equalTo(ParticipantAttribute.values().length)));
        assertThat("Unexpected test name in CSV line " + csvLine,
                   cells[ParticipantAttribute.TEST_NAME.ordinal()],
                   is(equalTo(testName)));
        assertThat("Unexpected client name in CSV line " + csvLine,
                   cells[ParticipantAttribute.CONFIGURED_CLIENT_NAME.ordinal()],
                   is(equalTo(clientName)));
        assertThat("Unexpected participant name in CSV line " + csvLine,
                   cells[ParticipantAttribute.PARTICIPANT_NAME.ordinal()],
                   is(equalTo(participantName)));
    }

    private String[] splitCsvCells(String csvLine)
    {
        int DONT_STRIP_EMPTY_LAST_FIELD_FLAG = -1;
        return csvLine.split(",", DONT_STRIP_EMPTY_LAST_FIELD_FLAG);
    }

    private File createTemporaryOutputDirectory() throws IOException
    {
        String tmpDir = System.getProperty("java.io.tmpdir");
        File csvDir = new File(tmpDir, getTestName() + "_" + System.currentTimeMillis());
        csvDir.mkdir();
        csvDir.deleteOnExit();
        return csvDir;
    }

    private File getJNDIPropertiesFile() throws Exception
    {
        String connectionUrl = getConnectionBuilder().setClientId(null).buildConnectionURL();
        String factoryClass = getProtocol() == Protocol.AMQP_1_0
                ? "org.apache.qpid.jms.jndi.JmsInitialContextFactory"
                : "org.apache.qpid.jndi.PropertiesFileInitialContextFactory";

        Properties properties = new Properties();
        properties.put("connectionfactory.connectionfactory", connectionUrl);
        properties.put("java.naming.factory.initial", factoryClass);
        properties.put("queue.controllerqueue", "controllerqueue");

        File propertiesFile = Files.createTempFile("perftests", ".jndi.properties").toFile();
        try (OutputStream os = new FileOutputStream(propertiesFile))
        {
            properties.store(os, null);
        }
        return propertiesFile;
    }

}
