/*
 * 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.johnzon.core;

import org.junit.Test;

import javax.json.Json;
import javax.json.JsonValue;
import javax.json.stream.JsonGenerator;
import javax.json.stream.JsonParser;
import java.io.ByteArrayInputStream;
import java.io.OutputStream;
import java.io.Writer;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;

import static javax.json.JsonValue.ValueType.ARRAY;
import static javax.json.JsonValue.ValueType.OBJECT;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

public class SnippetTest {

    @Test
    public void simple() {
        final JsonValue value = parse("{\"name\":\"string\",\"value\":\"string\",\"type\":\"string\"}");

        // This snippet is smaller than the allowed size.  It should show in entirety.
        assertSnippet(value, "{\"name\":\"string\",\"value\":\"string\",\"type\":\"string\"}", 100);

        // This snippet is exactly 50 characters when formatted.  We should see no "..." at the end.
        assertSnippet(value, "{\"name\":\"string\",\"value\":\"string\",\"type\":\"string\"}", 50);

        // This snippet is too large.  We should see the "..." at the end.
        assertSnippet(value, "{\"name\":\"string\",\"value\":\"stri...", 30);
    }

    @Test
    public void mapOfArray() {
        final JsonValue value = parse("{\"name\": [\"red\", \"green\", \"blue\"], \"value\": [\"orange\", \"yellow\", \"purple\"]}");

        assertSnippet(value, "{\"name\":[\"red\",\"green\",\"blue\"],\"value\":[\"orange\",\"yellow\",\"purple\"]}", 200);
        assertSnippet(value, "{\"name\":[\"red\",\"green\",\"blue\"],\"value\":[\"orange\",\"yellow\",\"purple\"]}", 68);
        assertSnippet(value, "{\"name\":[\"red\",\"green\",\"blue\"],\"value\":[\"orange\",\"...", 50);
    }

    @Test
    public void mapOfObject() {
        final JsonValue value = parse("{\"name\": {\"name\": \"red\", \"value\": \"green\", \"type\": \"blue\"}," +
                " \"value\": {\"name\": \"orange\", \"value\": \"purple\", \"type\": \"yellow\", \"scope\": \"brown\"}}");

        assertSnippet(value, "{\"name\":{\"name\":\"red\",\"value\":\"green\",\"type\":\"blue\"}," +
                "\"value\":{\"name\":\"orange\",\"value\":\"purple\",\"type\":\"yellow\",\"scope\":\"brown\"}}", 200);

        assertSnippet(value, "{\"name\":{\"name\":\"red\",\"value\":\"green\",\"type\":\"blue\"}," +
                "\"value\":{\"name\":\"orange\",\"value\":\"purple\",\"type\":\"yellow\",\"scope\":\"brown\"}}", 128);

        assertSnippet(value, "{\"name\":{\"name\":\"red\",\"value\":\"green\",\"type\":\"blue\"}," +
                "\"value\":{\"name\":\"orange\",\"value\":\"purple\",\"type...", 100);
    }

    @Test
    public void mapOfNestedMaps() {
        final JsonValue value = parse("{\"name\": {\"name\": {\"name\": {\"name\": \"red\", \"value\": \"green\", \"type\": \"blue\"}}}}");

        assertSnippet(value, "{\"name\":{\"name\":{\"name\":{\"name\":\"red\",\"value\":\"green\",\"type\":\"blue\"}}}}", 100);
        assertSnippet(value, "{\"name\":{\"name\":{\"name\":{\"name\":\"red\",\"value\":\"green\",\"type\":\"blue\"}}}}", 71);
        assertSnippet(value, "{\"name\":{\"name\":{\"name\":{\"name\":\"red\",\"value\":\"gre...", 50);
    }

    @Test
    public void mapOfString() {
        final JsonValue value = parse("{\"name\":\"string\",\"value\":\"string\",\"type\":\"string\"}");
        assertSnippet(value, "{\"name\":\"string\",\"value\":\"string\",\"type\":\"string\"}", 100);
        assertSnippet(value, "{\"name\":\"string\",\"value\":\"string\",\"type\":\"string\"}", 50);
        assertSnippet(value, "{\"name\":\"string\",\"value\":\"stri...", 30);
    }

    @Test
    public void mapOfNumber() {
        final JsonValue value = parse("{\"name\":1234,\"value\":5,\"type\":67890,\"scope\":null}");

        assertSnippet(value, "{\"name\":1234,\"value\":5,\"type\":67890,\"scope\":null}", 100);
        assertSnippet(value, "{\"name\":1234,\"value\":5,\"type\":67890,\"scope\":null}", 49);
        assertSnippet(value, "{\"name\":1234,\"value\":5,\"type\":...", 30);
    }

    @Test
    public void mapOfTrue() {
        final JsonValue value = parse("{\"name\":true,\"value\":true,\"type\":true,\"scope\":true}");

        assertSnippet(value, "{\"name\":true,\"value\":true,\"type\":true,\"scope\":true}", 60);
        assertSnippet(value, "{\"name\":true,\"value\":true,\"type\":true,\"scope\":true}", 51);
        assertSnippet(value, "{\"name\":true,\"value\":true,\"typ...", 30);
    }

    @Test
    public void mapOfFalse() {
        final JsonValue value = parse("{\"name\":false,\"value\":false,\"type\":false}");

        assertSnippet(value, "{\"name\":false,\"value\":false,\"type\":false}", 50);
        assertSnippet(value, "{\"name\":false,\"value\":false,\"type\":false}", 41);
        assertSnippet(value, "{\"name\":false,\"value...", 20);
    }

    @Test
    public void mapOfNull() {
        final JsonValue value = parse("{\"name\":null,\"value\":null,\"type\":null,\"scope\":null}");

        assertSnippet(value, "{\"name\":null,\"value\":null,\"type\":null,\"scope\":null}", 60);
        assertSnippet(value, "{\"name\":null,\"value\":null,\"type\":null,\"scope\":null}", 51);
        assertSnippet(value, "{\"name\":null,\"value\":null,\"typ...", 30);
    }

    @Test
    public void arrayOfArray() {
        final JsonValue value = parse("[[\"red\",\"green\"], [1,22,333], [{\"r\":  255,\"g\": 165}], [true, false]]");

        assertSnippet(value, "[[\"red\",\"green\"],[1,22,333],[{\"r\":255,\"g\":165}],[true,false]]", 100);
        assertSnippet(value, "[[\"red\",\"green\"],[1,22,333],[{\"r\":255,\"g\":165}],[true,false]]", 61);
        assertSnippet(value, "[[\"red\",\"green\"],[1,22,333],[{\"r\":255,\"g...", 40);
    }

    @Test
    public void arrayOfObject() {
        final JsonValue value = parse("[{\"r\":  255,\"g\": \"165\"},{\"g\":  0,\"a\": \"0\"},{\"transparent\": false}]");

        assertSnippet(value, "[{\"r\":255,\"g\":\"165\"},{\"g\":0,\"a\":\"0\"},{\"transparent\":false}]", 100);
        assertSnippet(value, "[{\"r\":255,\"g\":\"165\"},{\"g\":0,\"a\":\"0\"},{\"transparent\":false}]", 59);
        assertSnippet(value, "[{\"r\":255,\"g\":\"165\"},{\"g\":0,\"a...", 30);
    }

    @Test
    public void arrayOfString() {
        final JsonValue value = parse("[\"red\", \"green\", \"blue\", \"orange\", \"yellow\", \"purple\"]");

        assertSnippet(value, "[\"red\",\"green\",\"blue\",\"orange\",\"yellow\",\"purple\"]", 100);
        assertSnippet(value, "[\"red\",\"green\",\"blue\",\"orange\",\"yellow\",\"purple\"]", 49);
        assertSnippet(value, "[\"red\",\"green\",\"blue\",\"orange\"...", 30);
    }

    @Test
    public void arrayOfNumber() {
        final JsonValue value = parse("[1,22,333,4444,55555,666666,7777777,88888888,999999999]");

        assertSnippet(value, "[1,22,333,4444,55555,666666,7777777,88888888,999999999]", 100);
        assertSnippet(value, "[1,22,333,4444,55555,666666,7777777,88888888,999999999]", 55);
        assertSnippet(value, "[1,22,333,4444,55555,666666,77...", 30);
    }

    @Test
    public void arrayOfTrue() {
        final JsonValue value = parse("[true,true,true,true,true,true,true,true]");

        assertSnippet(value, "[true,true,true,true,true,true,true,true]", 100);
        assertSnippet(value, "[true,true,true,true,true,true,true,true]", 41);
        assertSnippet(value, "[true,true,true,true,true,true...", 30);
    }

    @Test
    public void arrayOfFalse() {
        final JsonValue value = parse("[false,false,false,false,false,false,false]");

        assertSnippet(value, "[false,false,false,false,false,false,false]", 100);
        assertSnippet(value, "[false,false,false,false,false,false,false]", 43);
        assertSnippet(value, "[false,false,false,false,false...", 30);
    }

    @Test
    public void arrayOfNull() {
        final JsonValue value = parse("[null,null,null,null,null,null]");

        assertSnippet(value, "[null,null,null,null,null,null]", 50);
        assertSnippet(value, "[null,null,null,null,null,null]", 31);
        assertSnippet(value, "[null,null,null...", 15);
    }

    @Test
    public void string() {
        final JsonValue value = parse("\"This is a \\\"string\\\" with quotes in it.  It should be properly escaped.\"");

        assertSnippet(value, "\"This is a \\\"string\\\" with quotes in it.  It should be properly escaped.\"", 100);
        assertSnippet(value, "\"This is a \\\"string\\\" with quotes in it.  It should be properly escaped.\"", 73);
        assertSnippet(value, "\"This is a \\\"string\\\" with quotes in it.  It shoul...", 50);
    }

    @Test
    public void number() {
        final JsonValue value = parse("1223334444555556666667777777.88888888999999999");

        assertSnippet(value, "1223334444555556666667777777.88888888999999999", 50);
        assertSnippet(value, "1223334444555556666667777777.88888888999999999", 46);
        assertSnippet(value, "1223334444555556666667777777.8...", 30);
    }

    @Test
    public void trueValue() {
        final JsonValue value = parse("true");

        assertSnippet(value, "true", 50);
        // we don't trim 'true' -- showing users something like 't...' doesn't make much sense
        assertSnippet(value, "t...", 1);
    }

    @Test
    public void falseValue() {
        final JsonValue value = parse("false");

        assertSnippet(value, "false", 50);
        // we don't trim 'false' -- showing users something like 'f...' doesn't make much sense
        assertSnippet(value, "f...", 1);
    }

    @Test
    public void nullValue() {
        final JsonValue value = parse("null");

        assertSnippet(value, "null", 50);
        // we don't trim 'null' -- showing users something like 'n...' doesn't make much sense
        assertSnippet(value, "n...", 1);
    }

    private JsonValue parse(final String json) {
        final JsonParser jsonParser = Json.createParser(new ByteArrayInputStream(json.getBytes()));
        return jsonParser.getValue();
    }

    private void assertSnippet(final JsonValue object, final String expected, final int i) {
        final TrackingJsonGeneratorFactory factory = new TrackingJsonGeneratorFactory();
        final String actual = new Snippet(i, factory).of(object);

        // Assert the resulting string contents
        assertEquals(expected, actual);

        // Assert the resulting string length
        if (expected.endsWith("...")) {
            assertEquals(i + 3, actual.length());
        } else {
            assertTrue(actual.length() <= i);
        }

        /*
         * Close methods are supposed to idempotent and
         * safe to call many times, but let's be nice and
         * ensure it is only called once.
         */
        assertEquals(1, factory.calls.stream()
                .filter("close()"::equals)
                .count());

        /*
         * When writing arrays or objects, assert we stopped
         * calling write methods on the JsonGenerator once the
         * end of the snippet is reached.
         */
        if (expected.endsWith("...") && isType(object, ARRAY, OBJECT)) {
            /*
             * Serialize the json value, truncating nothing
             */
            final TrackingJsonGeneratorFactory full = new TrackingJsonGeneratorFactory();
            new Snippet(8192, full).of(object);

            /*
             * Assert that the calls made in truncated version are less
             * than when we serialized the entire json value.
             */
            assertTrue(factory.calls.size() < full.calls.size());
        }
    }

    private static boolean isType(final JsonValue value, final JsonValue.ValueType... types) {
        for (final JsonValue.ValueType type : types) {
            if (value.getValueType() == type) {
                return true;
            }
        }
        return false;
    }

    /**
     * Track all calls made to JsonGenerator so we can ensure Snippet is
     * not trying to serialize entire Json documents.  Despite the output
     * of Snippet appearing properly truncated, buffering can still cause
     * the entire json value to be serialized.
     *
     * The only way to test this is not happening is to track all calls
     * made to the JsonGenerator and assert they do in fact stop.
     */
    public static class TrackingJsonGeneratorFactory extends JsonGeneratorFactoryImpl {
        private final List<String> calls = new ArrayList<>();

        public TrackingJsonGeneratorFactory() {
            super(Collections.EMPTY_MAP);
        }

        @Override
        public JsonGenerator createGenerator(final OutputStream out) {
            return new TrackingGenerator(super.createGenerator(out));
        }

        @Override
        public JsonGenerator createGenerator(final Writer writer) {
            return new TrackingGenerator(super.createGenerator(writer));
        }

        class TrackingGenerator implements JsonGenerator {

            private final JsonGenerator delegate;

            public TrackingGenerator(final JsonGenerator delegate) {
                record("<init>");
                this.delegate = delegate;
            }

            private void record(final String method, final Object... args) {
                final String argString = Stream.of(args)
                        .map(Object::toString)
                        .reduce((s, s2) -> s + "," + s2)
                        .orElse("");
                calls.add(String.format("%s(%s)", method, argString));
            }

            public List<String> getCalls() {
                return calls;
            }

            @Override
            public JsonGenerator writeStartObject() {
                record("writeStartObject");
                return delegate.writeStartObject();
            }

            @Override
            public JsonGenerator writeStartObject(final String name) {
                record("writeStartObject", name);
                return delegate.writeStartObject(name);
            }

            @Override
            public JsonGenerator writeStartArray() {
                record("writeStartArray");
                return delegate.writeStartArray();
            }

            @Override
            public JsonGenerator writeStartArray(final String name) {
                record("writeStartArray", name);
                return delegate.writeStartArray(name);
            }

            @Override
            public JsonGenerator writeKey(final String name) {
                record("writeKey", name);
                return delegate.writeKey(name);
            }

            @Override
            public JsonGenerator write(final String name, final JsonValue value) {
                record("write", name, value.getValueType());
                assertJsonType(value);
                return delegate.write(name, value);
            }

            @Override
            public JsonGenerator write(final String name, final String value) {
                record("write", name, value);
                return delegate.write(name, value);
            }

            @Override
            public JsonGenerator write(final String name, final BigInteger value) {
                record("write", name, value);
                return delegate.write(name, value);
            }

            @Override
            public JsonGenerator write(final String name, final BigDecimal value) {
                record("write", name, value);
                return delegate.write(name, value);
            }

            @Override
            public JsonGenerator write(final String name, final int value) {
                record("write", name, value);
                return delegate.write(name, value);
            }

            @Override
            public JsonGenerator write(final String name, final long value) {
                record("write", name, value);
                return delegate.write(name, value);
            }

            @Override
            public JsonGenerator write(final String name, final double value) {
                record("write", name, value);
                return delegate.write(name, value);
            }

            @Override
            public JsonGenerator write(final String name, final boolean value) {
                record("write", name, value);
                return delegate.write(name, value);
            }

            @Override
            public JsonGenerator writeNull(final String name) {
                record("writeNull");
                return delegate.writeNull(name);
            }

            @Override
            public JsonGenerator writeEnd() {
                record("writeEnd");
                return delegate.writeEnd();
            }

            @Override
            public JsonGenerator write(final JsonValue value) {
                record("write", value.getValueType());
                assertJsonType(value);
                return delegate.write(value);
            }

            @Override
            public JsonGenerator write(final String value) {
                record("write", value);
                return delegate.write(value);
            }

            @Override
            public JsonGenerator write(final BigDecimal value) {
                record("write", value);
                return delegate.write(value);
            }

            @Override
            public JsonGenerator write(final BigInteger value) {
                record("write", value);
                return delegate.write(value);
            }

            @Override
            public JsonGenerator write(final int value) {
                record("write", value);
                return delegate.write(value);
            }

            @Override
            public JsonGenerator write(final long value) {
                record("write", value);
                return delegate.write(value);
            }

            @Override
            public JsonGenerator write(final double value) {
                record("write", value);
                return delegate.write(value);
            }

            @Override
            public JsonGenerator write(final boolean value) {
                record("write", value);
                return delegate.write(value);
            }

            @Override
            public JsonGenerator writeNull() {
                record("writeNull");
                return delegate.writeNull();
            }

            @Override
            public void close() {
                record("close");
                delegate.close();
            }

            @Override
            public void flush() {
                record("flush");
                delegate.flush();
            }

            /**
             * Snippet should not be asking the JsonGenerator to be serializing
             * an objet or an array as this would cause the entire portion of
             * json to be written even if we need a small chunk.
             */
            private void assertJsonType(final JsonValue value) {
                if (isType(value, ARRAY, OBJECT)) {
                    fail("should never be called");
                }
            }
        }
    }

}
