/*
 * 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.pipes.internal;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.pipes.AbstractPipeTest;
import org.apache.sling.pipes.ExecutionResult;
import org.apache.sling.pipes.PipeBuilder;
import org.apache.sling.testing.mock.sling.ResourceResolverType;
import org.apache.sling.testing.mock.sling.junit.SlingContext;
import org.apache.sling.testing.mock.sling.servlet.MockRequestPathInfo;
import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletRequest;
import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletResponse;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static org.apache.sling.pipes.internal.CommandExecutorImpl.PARAMS_SEPARATOR;
import static org.apache.sling.pipes.internal.CommandUtil.keyValuesToArray;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import javax.json.JsonArray;
import javax.json.JsonObject;
import javax.json.JsonString;
import javax.servlet.ServletException;

public class CommandExecutorImplTest extends AbstractPipeTest {

    CommandExecutorImpl commands;

    @Before
    public void setup() throws PersistenceException {
        super.setup();
        context = new SlingContext(ResourceResolverType.JCR_OAK);
        context.load().json("/initial-content/content/fruits.json", PATH_FRUITS);
        commands = new CommandExecutorImpl();
        commands.plumber = plumber;
    }

    @Test
    public void getSublist() {
        assertArrayEquals(new String[]{"check", "this"}, commands.getSpaceSeparatedTokens("check this").toArray());
        assertArrayEquals(new String[]{"and", "now","check this"}, commands.getSpaceSeparatedTokens("and now \"check this\"").toArray());
    }

        @Test
    public void testParseTokens() {
        List<CommandExecutorImpl.Token> tokens = commands.parseTokens("some isolated items");
        assertEquals("there should be 1 token", 1, tokens.size());
        CommandExecutorImpl.Token token = tokens.get(0);
        assertEquals("pipe key should be 'some'", "some", token.pipeKey);
        assertEquals("pipe args should be isolated, items", Arrays.asList("isolated", "items"), token.args);
    }
    @Test
    public void testParseTokensWithQuotes() {
        String tokenString = "first arg | second firstarg secondarg @ name second | third blah";
        List<CommandExecutorImpl.Token> tokens = commands.parseTokens(tokenString);
        assertEquals("there should be 3 tokens", 3, tokens.size());
        assertEquals("keys check", Arrays.asList("first","second", "third"), tokens.stream().map(t -> t.pipeKey).collect(Collectors.toList()));
        assertEquals("params check", "second", tokens.get(1).options.name);
    }

    @Test
    public void testParseJson() {
        String tokenString = "json [{\"title\":\"this is the first\", \"path\":\"/content/nested/two\"}, {\"title\":\"this is the second\", \"path\":\"/content/nested/three\"}]";
        List<CommandExecutorImpl.Token> tokens = commands.parseTokens(tokenString);
        assertEquals("there should be 1 token", 1, tokens.size());
        assertEquals("there should be 1 arg", 1, tokens.get(0).args.size());
    }

    @Test
    public void testQuotedTokens() {
        List<CommandExecutorImpl.Token> tokens = commands.parseTokens("some isolated items \"with quotes\"");
        assertEquals("there should be 1 token", 1, tokens.size());
        CommandExecutorImpl.Token token = tokens.get(0);
        assertEquals("pipe args should be isolated, items", Arrays.asList("isolated", "items", "with quotes"), token.args);
    }

    @Test
    public void testKeyValueToArray() {
        assertArrayEquals("1", new String[]{"one","two","three","four"}, keyValuesToArray(Arrays.asList("one=two","three=four")));
        assertArrayEquals("2", new String[]{"one","two","three","${four}"}, keyValuesToArray(Arrays.asList("one=two","three=${four}")));
        assertArrayEquals("3", new String[]{"${one == 'check'? 'three':'four'}","two"}, keyValuesToArray((Arrays.asList("${one == 'check'? 'three':'four'}=two"))));
        assertArrayEquals("4", new String[]{"a_b-c","two"}, keyValuesToArray((Arrays.asList("a_b-c=two"))));
        assertArrayEquals("5", new String[]{"one","two","three","${four == 'blah' ? 'five' : 'six'}"},
            keyValuesToArray(Arrays.asList("one=two","three=${four == 'blah' ? 'five' : 'six'}")));
        assertArrayEquals("6", new String[]{"jcr:content/singer","${'ringo' == one ? false : true}"}, keyValuesToArray(Arrays.asList("jcr:content/singer=${'ringo' == one ? false : true}")));
    }

    @Test
    public void testSimpleExpression() throws Exception {
        PipeBuilder builder = commands.parse(context.resourceResolver(),"echo /content/fruits");
        assertTrue("there should be a resource", builder.build().getOutput().hasNext());
    }

    @Test
    public void testSimpleChainedConf() throws Exception {
        PipeBuilder builder = commands.parse(context.resourceResolver(),"echo /content/fruits | write some=test key=value");
        assertNotNull("there should be a resource", builder.run());
        ValueMap props = context.currentResource(PATH_FRUITS).getValueMap();
        assertEquals("there should some=test", "test", props.get("some"));
        assertEquals("there should key=value", "value", props.get("key"));
    }

    @Test
    public void testOptions() {
        String expected = "works";
        String optionString = "name works @ path works @ expr works @ with one=works two=works @ outputs one=works two=works";
        CommandExecutorImpl.Options options = commands.getOptions(optionString.split(PARAMS_SEPARATOR));
        assertEquals("check name", expected, options.name);
        assertEquals("check expr", expected, options.expr);
        assertEquals("check path", expected, options.path);
        Map bindings = new HashMap();
        CommandUtil.writeToMap(bindings, true, options.with);
        assertEquals("check with first", expected, bindings.get("one"));
        assertEquals("check with second", expected, bindings.get("two"));
        assertNotNull("a writer should have been created", options.outputs);
    }

    @Test
    public void testOptionsListsWithOneItem() {
        String expected = "works";
        String optionString = "with one=works @ outputs one=works";
        CommandExecutorImpl.Options options = commands.getOptions(optionString.split(PARAMS_SEPARATOR));
        Map bindings = new HashMap();
        CommandUtil.writeToMap(bindings, true, options.with);
        assertEquals("check with first", expected, bindings.get("one"));
        assertNotNull("a writer should have been created", options.outputs);
    }

    @Test
    public void testChainedConfWithInternalOptions() throws Exception {
        PipeBuilder builder = commands.parse(context.resourceResolver(),
        "echo /content/fruits @ name fruits | write some=${path.fruits} key=value");
        assertNotNull("there should be a resource", builder.run());
        ValueMap props = context.currentResource(PATH_FRUITS).getValueMap();
        assertEquals("there should some=/content/fruits", PATH_FRUITS, props.get("some"));
        assertEquals("there should key=value", "value", props.get("key"));
    }

    @Test
    public void adaptToDemoTest() throws Exception {
        String url = "'http://99-bottles-of-beer.net/lyrics.html'";
        String cmd = "egrep " + url + " @ name bottles @ with pattern=(?<number>\\d(\\d)?) | mkdir /var/bottles/${bottles.number}";
        PipeBuilder builder = commands.parse(context.resourceResolver(), cmd);
        ContainerPipe pipe = (ContainerPipe)builder.build();
        ValueMap regexp = pipe.getResource().getChild("conf/bottles").getValueMap();
        assertEquals("we expect expr to be the url", url, regexp.get("expr"));
    }

    @Test
    public void testExecuteWithWriter() throws Exception {
        PipeBuilder builder = plumber.newPipe(context.resourceResolver()).echo("/content/${node}").$("nt:base");
        String path = builder.build().getResource().getPath();
        ExecutionResult result = commands.execute(context.resourceResolver(), path, "outputs title=two['jcr:title'] desc=two['jcr:description']", "with node=fruits");
        assertNotNull(result);
    }

    String testRawServlet(Map<String,Object> params) throws IOException {
        MockSlingHttpServletRequest request = context.request();
        MockSlingHttpServletResponse response = context.response();
        request.setParameterMap(params);
        MockRequestPathInfo pathInfo = (MockRequestPathInfo)request.getRequestPathInfo();
        pathInfo.setExtension("json");
        request.setMethod("POST");
        commands.doPost(request, response);
        if (response.getStatus() != 200) {
            System.out.println(response.getOutputAsString());
        }
        assertEquals(200, response.getStatus());
        return response.getOutputAsString();
    }
    JsonObject testServlet(Map<String,Object> params) throws ServletException, IOException {
        return (JsonObject) JsonUtil.parse(testRawServlet(params));
    }

    @Test
    public void testHelp() throws ServletException, IOException {
        Map<String, Object> params = new HashMap<>();
        params.put(CommandExecutorImpl.REQ_PARAM_HELP, "blah");
        String response = testRawServlet(params);
        assertTrue(StringUtils.isNotBlank(response));
    }

    @Test
    public void testSimpleCommandServlet() throws IOException, ServletException {
        Map<String, Object> params = new HashMap<>();
        params.put(CommandExecutorImpl.REQ_PARAM_CMD, "echo /content | mkdir foo | write type=bar");
        JsonObject response = testServlet(params);
        assertEquals(1, response.getJsonNumber("size").intValue());
        assertEquals("/content/foo", response.getJsonArray("items").getString(0));
    }

    @Test
    public void testMultipeLineGetCommandLine() throws IOException, ServletException {
        Map<String, Object> params = new HashMap<>();
        params.put(CommandExecutorImpl.REQ_PARAM_FILE, IOUtils.toString(getClass().getResourceAsStream("/commandsFormats"
            + ".txt"), "UTF-8"));
        MockSlingHttpServletRequest request = context.request();
        request.setParameterMap(params);
        request.setMethod("POST");
        List<String> cmdList = commands.getCommandList(context.request());
        assertEquals(5, cmdList.size());
        for (int i = 0; i < 3; i ++) {
            assertEquals("echo /content | $ /apps/pipes-it/fruit | children nt:unstructured", cmdList.get(i));
        }
        assertEquals ("echo /content | write one=foo nested/two=foo nested/three=foo", cmdList.get(3));
        assertEquals("echo /content | json [{\"title\":\"this is the first\", \"path\":\"/content/nested/two\"}, {\"title\":\"this is the second\", \"path\":\"/content/nested/three\"}] @ name test | echo ${test.path}", cmdList.get(4));
    }

    String[] getItemsArray(JsonObject response) {
        JsonArray jsonItems = response.getJsonArray("items");
        List<String> items = jsonItems.stream().map(o -> ((JsonString)o).getString()).collect(Collectors.toList());
        return items.toArray(new String[jsonItems.size()]);
    }

    @Test
    public void testChainedCommand() throws IOException, ServletException {
        Map<String, Object> params = new HashMap<>();
        params.put(CommandExecutorImpl.REQ_PARAM_FILE, IOUtils.toString(getClass().getResourceAsStream("/chainedCommand"
            + ".txt"), "UTF-8"));
        JsonObject response = testServlet(params);
        assertEquals(5, response.getJsonNumber("size").intValue());
        assertArrayEquals(new String[]{ "/content/fruits/banana/isnota/pea","/content/fruits/banana/isnota/carrot",
            "/content/fruits/apple/isnota/pea","/content/fruits/apple/isnota/plum",
            "/content/fruits/apple/isnota/carrot"}, getItemsArray(response));
    }

    @Test
    public void testFileCommandServlet() throws IOException, ServletException {
        Map<String, Object> params = new HashMap<>();
        params.put(CommandExecutorImpl.REQ_PARAM_FILE, IOUtils.toString(getClass().getResourceAsStream("/testcommand"
                + ".txt"), "UTF-8"));
        JsonObject response = testServlet(params);
        assertEquals(5, response.getJsonNumber("size").intValue());
        assertArrayEquals(new String[]{"/content/beatles/john", "/content/beatles/paul", "/content/beatles/georges",
                "/content/beatles/ringo", "/content/beatles/ringo/jcr:content"}, getItemsArray(response));
    }
}