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

import java.io.StringReader;
import java.io.StringWriter;

import javax.json.Json;
import javax.json.JsonObject;
import javax.servlet.http.HttpServletRequest;

import ch.qos.logback.classic.Level;
import org.junit.Test;
import org.slf4j.MDC;
import org.slf4j.helpers.FormattingTuple;
import org.slf4j.helpers.MessageFormatter;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class JSONRecordingTest {
    static final String MDC_QUERY_ID = "oak.query.id";
    static String QE_LOGGER = "org.apache.jackrabbit.oak.query.QueryImpl";
    static String UNION_QUERY_LOGGER = "org.apache.jackrabbit.oak.query.UnionQueryImpl";
    private HttpServletRequest request = mock(HttpServletRequest.class);

    private TracerConfig tc = new TracerConfig(TracerContext.QUERY_LOGGER, Level.INFO);

    @Test
    public void logQueries() throws Exception{
        StringWriter sw = new StringWriter();

        when(request.getMethod()).thenReturn("GET");
        JSONRecording r = new JSONRecording("abc", request, true);

        MDC.put(MDC_QUERY_ID, "1");
        r.log(tc, Level.DEBUG, "org.apache.jackrabbit.oak.query.QueryEngineImpl",
                tuple("Parsing {} statement: {}",  "XPATH", "SELECT FOO"));
        r.log(tc, Level.DEBUG, QE_LOGGER, tuple("query plan FOO PLAN"));

        r.done();
        r.render(sw);

        JsonObject json = Json.createReader(new StringReader(sw.toString())).readObject();
        assertEquals("GET", json.getString("method"));
        assertTrue(json.containsKey("time"));
        assertTrue(json.containsKey("timestamp"));
        assertEquals(1, json.getJsonArray("queries").size());
    }

    @Test
    public void logUnionQueries() throws Exception{
        StringWriter sw = new StringWriter();

        when(request.getMethod()).thenReturn("GET");
        JSONRecording r = new JSONRecording("abc", request, true);

        MDC.put(MDC_QUERY_ID, "1");
        r.log(tc, Level.DEBUG, "org.apache.jackrabbit.oak.query.QueryEngineImpl",
                tuple("Parsing {} statement: {}",  "XPATH", "SELECT FOO BAR"));
        r.log(tc, Level.DEBUG, UNION_QUERY_LOGGER, tuple("query union plan FOO PLAN */ union BAR PLAN", "FOO PLAN */ union BAR PLAN"));
        // Two sub-query plans for the split union
        r.log(tc, Level.DEBUG, QE_LOGGER, tuple("query plan FOO PLAN", "xpath", "FOO PLAN"));
        r.log(tc, Level.DEBUG, QE_LOGGER, tuple("query plan BAR PLAN", "xpath", "BAR PLAN"));


        MDC.put(MDC_QUERY_ID, "2");
        r.log(tc, Level.DEBUG, "org.apache.jackrabbit.oak.query.QueryEngineImpl",
                tuple("Parsing {} statement: {}",  "XPATH", "SELECT FOO"));
        r.log(tc, Level.DEBUG, QE_LOGGER, tuple("query plan FOO PLAN", "xpath", "FOO PLAN"));

        r.done();
        r.render(sw);

        JsonObject json = Json.createReader(new StringReader(sw.toString())).readObject();
        assertEquals("GET", json.getString("method"));
        assertFalse(json.isNull("time"));
        assertFalse(json.isNull("timestamp"));
        assertEquals(2, json.getJsonArray("queries").size());

        assertEquals(json.getJsonArray("queries").getJsonObject(0).getString("query"), "SELECT FOO BAR");
        assertEquals(json.getJsonArray("queries").getJsonObject(0).getString("plan"), "FOO PLAN */ union BAR PLAN");

        assertEquals(json.getJsonArray("queries").getJsonObject(1).getString("query"), "SELECT FOO");
        assertEquals(json.getJsonArray("queries").getJsonObject(1).getString("plan"), "FOO PLAN");
    }

    @Test
    public void requestTrackerLogs() throws Exception{
        StringWriter sw = new StringWriter();
        JSONRecording r = new JSONRecording("abc", request, true);

        r.registerTracker(TestUtil.createTracker("x", "y"));

        r.done();
        r.render(sw);

        JsonObject json = Json.createReader(new StringReader(sw.toString())).readObject();
        assertEquals(2, json.getJsonArray("requestProgressLogs").size());
    }

    @Test
    public void logs() throws Exception{
        StringWriter sw = new StringWriter();
        JSONRecording r = new JSONRecording("abc", request, true);

        FormattingTuple tp1 = MessageFormatter.arrayFormat("{} is going", new Object[]{"Jack"});
        r.log(tc, Level.INFO, "foo", tp1);
        r.log(tc, Level.WARN, "foo.bar", MessageFormatter.arrayFormat("Jill is going", null));
        r.log(tc, Level.ERROR, "foo.bar",
                MessageFormatter.arrayFormat("Jack and {} is going", new Object[]{"Jill" , new Exception()}));

        r.done();
        r.render(sw);

        JsonObject json = Json.createReader(new StringReader(sw.toString())).readObject();
        assertEquals(3, json.getJsonArray("logs").size());

        JsonObject l1 = json.getJsonArray("logs").getJsonObject(0);
        assertEquals("INFO", l1.getString("level"));
        assertEquals("foo", l1.getString("logger"));
        assertEquals(tp1.getMessage(), l1.getString("message"));
        assertEquals(1, l1.getJsonArray("params").size());
        assertFalse(l1.containsKey("exception"));
        assertFalse(l1.containsKey("caller"));
        assertTrue(l1.containsKey("timestamp"));

        JsonObject l3 = json.getJsonArray("logs").getJsonObject(2);
        assertNotNull(l3.get("exception"));
    }

    @Test
    public void logsWithCaller() throws Exception{
        StringWriter sw = new StringWriter();
        final JSONRecording r = new JSONRecording("abc", request, true);

        TracerConfig config = new TracerConfig(TracerContext.QUERY_LOGGER,
                Level.INFO, new CallerStackReporter(20));
        r.log(config, Level.INFO, "foo", tuple("foo"));

        r.done();
        r.render(sw);

        JsonObject json = Json.createReader(new StringReader(sw.toString())).readObject();
        JsonObject l1 = json.getJsonArray("logs").getJsonObject(0);
        assertTrue(l1.containsKey("caller"));
        assertTrue(l1.getJsonArray("caller").size() > 0);
    }

    private static FormattingTuple tuple(String msg){
        return MessageFormatter.format(msg, null);
    }

    private static FormattingTuple tuple(String msg, String ... params){
        return MessageFormatter.arrayFormat(msg, params);
    }
}
