/*
 * 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.logging.log4j.layout.template.json.util;

import org.apache.logging.log4j.util.Strings;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Callable;

public final class StringParameterParser {

    private StringParameterParser() {}

    public static final class Values {

        private Values() {}

        static NullValue nullValue() {
            return NullValue.INSTANCE;
        }

        static StringValue stringValue(final String string) {
            return new StringValue(string);
        }

        static DoubleQuotedStringValue doubleQuotedStringValue(
                final String doubleQuotedString) {
            return new DoubleQuotedStringValue(doubleQuotedString);
        }

    }

    public interface Value {}

    public static final class NullValue implements Value {

        private static final NullValue INSTANCE = new NullValue();

        private NullValue() {}

        @Override
        public String toString() {
            return null;
        }

    }

    public static final class StringValue implements Value {

        private final String string;

        private StringValue(String string) {
            this.string = string;
        }

        public String getString() {
            return string;
        }

        @Override
        public boolean equals(Object object) {
            if (this == object) return true;
            if (object == null || getClass() != object.getClass()) return false;
            StringValue that = (StringValue) object;
            return string.equals(that.string);
        }

        @Override
        public int hashCode() {
            return Objects.hash(string);
        }

        @Override
        public String toString() {
            return string;
        }

    }

    public static final class DoubleQuotedStringValue implements Value {

        private final String doubleQuotedString;

        private DoubleQuotedStringValue(String doubleQuotedString) {
            this.doubleQuotedString = doubleQuotedString;
        }

        public String getDoubleQuotedString() {
            return doubleQuotedString;
        }

        @Override
        public boolean equals(Object object) {
            if (this == object) return true;
            if (object == null || getClass() != object.getClass()) return false;
            DoubleQuotedStringValue that = (DoubleQuotedStringValue) object;
            return doubleQuotedString.equals(that.doubleQuotedString);
        }

        @Override
        public int hashCode() {
            return Objects.hash(doubleQuotedString);
        }

        @Override
        public String toString() {
            return doubleQuotedString.replaceAll("\\\\\"", "\"");
        }

    }

    private enum State { READING_KEY, READING_VALUE }

    private static final class Parser implements Callable<Map<String, Value>> {

        private final String input;

        private final Map<String, Value> map;

        private State state;

        private int i;

        private String key;

        private Parser(final String input) {
            this.input = Objects.requireNonNull(input, "input");
            this.map = new LinkedHashMap<>();
            this.state = State.READING_KEY;
            this.i = 0;
            this.key = null;
        }

        @Override
        public Map<String, Value> call() {
            while (true) {
                skipWhitespace();
                if (i >= input.length()) {
                    break;
                }
                switch (state) {
                    case READING_KEY:
                        readKey();
                        break;
                    case READING_VALUE:
                        readValue();
                        break;
                    default:
                        throw new IllegalStateException("unknown state: " + state);
                }
            }
            if (state == State.READING_VALUE) {
                map.put(key, Values.nullValue());
            }
            return map;
        }

        private void readKey() {
            final int eq = input.indexOf('=', i);
            final int co = input.indexOf(',', i);
            final int j;
            final int nextI;
            if (eq < 0 && co < 0) {
                // Neither '=', nor ',' was found.
                j = nextI = input.length();
            } else if (eq < 0) {
                // Found ','.
                j = nextI = co;
            } else if (co < 0) {
                // Found '='.
                j = eq;
                nextI = eq + 1;
            } else if (eq < co) {
                // Found '=...,'.
                j = eq;
                nextI = eq + 1;
            } else {
                // Found ',...='.
                j = co;
                nextI = co;
            }
            key = input.substring(i, j).trim();
            if (Strings.isEmpty(key)) {
                final String message = String.format(
                        "failed to locate key at index %d: %s",
                        i, input);
                throw new IllegalArgumentException(message);
            }
            if (map.containsKey(key)) {
                final String message = String.format(
                        "conflicting key at index %d: %s",
                        i, input);
                throw new IllegalArgumentException(message);
            }
            state = State.READING_VALUE;
            i = nextI;
        }

        private void readValue() {
            final boolean doubleQuoted = input.charAt(i) == '"';
            if (doubleQuoted) {
                readDoubleQuotedStringValue();
            } else {
                readStringValue();
            }
            key = null;
            state = State.READING_KEY;
        }

        private void readDoubleQuotedStringValue() {
            int j = i + 1;
            while (j < input.length()) {
                if (input.charAt(j) == '"' && input.charAt(j - 1) != '\\') {
                    break;
                } else {
                    j++;
                }
            }
            if (j >= input.length()) {
                final String message = String.format(
                        "failed to locate the end of double-quoted content starting at index %d: %s",
                        i, input);
                throw new IllegalArgumentException(message);
            }
            final String content = input
                    .substring(i + 1, j)
                    .replaceAll("\\\\\"", "\"");
            final Value value = Values.doubleQuotedStringValue(content);
            map.put(key, value);
            i = j + 1;
            skipWhitespace();
            if (i < input.length()) {
                if (input.charAt(i) != ',') {
                    final String message = String.format(
                            "was expecting comma at index %d: %s",
                            i, input);
                    throw new IllegalArgumentException(message);
                }
                i++;
            }
        }

        private void skipWhitespace() {
            while (i < input.length()) {
                final char c = input.charAt(i);
                if (!Character.isWhitespace(c)) {
                    break;
                } else {
                    i++;
                }
            }
        }

        private void readStringValue() {
            int j = input.indexOf(',', i/* + 1*/);
            if (j < 0) {
                j = input.length();
            }
            final String content = input.substring(i, j);
            final String trimmedContent = content.trim();
            final Value value = trimmedContent.isEmpty()
                    ? Values.nullValue()
                    : Values.stringValue(trimmedContent);
            map.put(key, value);
            i += content.length() + 1;
        }

    }

    public static Map<String, Value> parse(final String input) {
        return parse(input, null);
    }

    public static Map<String, Value> parse(
            final String input,
            final Set<String> allowedKeys) {
        if (Strings.isBlank(input)) {
            return Collections.emptyMap();
        }
        final Map<String, Value> map = new Parser(input).call();
        final Set<String> actualKeys = map.keySet();
        for (final String actualKey : actualKeys) {
            final boolean allowed = allowedKeys == null || allowedKeys.contains(actualKey);
            if (!allowed) {
                final String message = String.format(
                        "unknown key \"%s\" is found in input: %s",
                        actualKey, input);
                throw new IllegalArgumentException(message);
            }
        }
        return map;
    }

}
