/*
 * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package jdk.jfr.internal;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;

import jdk.jfr.EventType;

/**
 * Metadata about a chunk
 */
public final class MetadataDescriptor {

    static final class Attribute {
        final String name;
        final String value;

        private Attribute(String name, String value) {
            this.name = name;
            this.value = value;
        }
    }

    static final class Element {
        final String name;
        final List<Element> elements = new ArrayList<>();
        final List<Attribute> attributes = new ArrayList<>();

        Element(String name) {
            this.name = name;
        }

        long longValue(String name) {
            String v = attribute(name);
            if (v != null)
                return Long.parseLong(v);
            else
                throw new IllegalArgumentException(name);
        }

        String attribute(String name) {
            for (Attribute a : attributes) {
                if (a.name.equals(name)) {
                    return a.value;
                }
            }
            return null;
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            try {
                prettyPrintXML(sb, "", this);
            } catch (IOException e) {
                // should not happen
            }
            return sb.toString();
        }

        long attribute(String name, long defaultValue) {
            String text = attribute(name);
            if (text == null) {
                return defaultValue;
            }
            return Long.parseLong(text);
        }

        String attribute(String name, String defaultValue) {
            String text = attribute(name);
            if (text == null) {
                return defaultValue;
            }
            return text;
        }

        List<Element> elements(String... names) {
            List<Element> filteredElements = new ArrayList<>();
            for (String name : names) {
                for (Element e : elements) {
                    if (e.name.equals(name)) {
                        filteredElements.add(e);
                    }
                }
            }
            return filteredElements;
        }

        void add(Element element) {
            elements.add(element);
        }

        void addAttribute(String name, Object value) {
            attributes.add(new Attribute(name, String.valueOf(value)));
        }

        Element newChild(String name) {
            Element e = new Element(name);
            elements.add(e);
            return e;
        }

        public void addArrayAttribute(Element element, String name, Object value) {
            String typeName = value.getClass().getComponentType().getName();
            switch (typeName) {
            case "int":
                int[] ints = (int[]) value;
                for (int i = 0; i < ints.length; i++) {
                    addAttribute(name  + "-" + i , ints[i]);
                }
                break;
            case "long":
                long[] longs = (long[]) value;
                for (int i = 0; i < longs.length; i++) {
                    addAttribute(name  + "-" + i , longs[i]);
                }
                break;
            case "float":
                float[] floats = (float[]) value;
                for (int i = 0; i < floats.length; i++) {
                    addAttribute(name  + "-" + i , floats[i]);
                }
                break;

            case "double":
                double[] doubles = (double[]) value;
                for (int i = 0; i < doubles.length; i++) {
                    addAttribute(name  + "-" + i , doubles[i]);
                }
                break;
            case "short":
                short[] shorts = (short[]) value;
                for (int i = 0; i < shorts.length; i++) {
                    addAttribute(name  + "-" + i , shorts[i]);
                }
                break;
            case "char":
                char[] chars = (char[]) value;
                for (int i = 0; i < chars.length; i++) {
                    addAttribute(name  + "-" + i , chars[i]);
                }
                break;
            case "byte":
                byte[] bytes = (byte[]) value;
                for (int i = 0; i < bytes.length; i++) {
                    addAttribute(name  + "-" + i , bytes[i]);
                }
                break;
            case "boolean":
                boolean[] booleans = (boolean[]) value;
                for (int i = 0; i < booleans.length; i++) {
                    addAttribute(name  + "-" + i , booleans[i]);
                }
                break;
            case "java.lang.String":
                String[] strings = (String[]) value;
                for (int i = 0; i < strings.length; i++) {
                    addAttribute(name  + "-" + i , strings[i]);
                }
                break;
            default:
                throw new InternalError("Array type of " + typeName + " is not supported");
            }
        }
    }

    static final String ATTRIBUTE_ID = "id";
    static final String ATTRIBUTE_SIMPLE_TYPE = "simpleType";
    static final String ATTRIBUTE_GMT_OFFSET = "gmtOffset";
    static final String ATTRIBUTE_LOCALE = "locale";
    static final String ELEMENT_TYPE = "class";
    static final String ELEMENT_SETTING = "setting";
    static final String ELEMENT_ANNOTATION = "annotation";
    static final String ELEMENT_FIELD = "field";
    static final String ATTRIBUTE_SUPER_TYPE = "superType";
    static final String ATTRIBUTE_TYPE_ID = "class";
    static final String ATTRIBUTE_DIMENSION = "dimension";
    static final String ATTRIBUTE_NAME = "name";
    static final String ATTRIBUTE_CONSTANT_POOL = "constantPool";
    static final String ATTRIBUTE_DEFAULT_VALUE = "defaultValue";

    final List<EventType> eventTypes = new ArrayList<>();
    final Collection<Type> types = new ArrayList<>();
    long gmtOffset;
    String locale;
    Element root;

    // package private
    MetadataDescriptor() {
    }

    private static void prettyPrintXML(Appendable sb, String indent, Element e) throws IOException {
        sb.append(indent + "<" + e.name);
        for (Attribute a : e.attributes) {
            sb.append(" ").append(a.name).append("=\"").append(a.value).append("\"");
        }
        if (e.elements.size() == 0) {
            sb.append("/");
        }
        sb.append(">\n");
        for (Element child : e.elements) {
            prettyPrintXML(sb, indent + "  ", child);
        }
        if (e.elements.size() != 0) {
            sb.append(indent).append("</").append(e.name).append(">\n");
        }
    }

    public Collection<Type> getTypes() {
        return types;
    }

    public List<EventType> getEventTypes() {
        return eventTypes;
    }

    public int getGMTOffset() {
        return (int) gmtOffset;
    }

    public String getLocale() {
        return locale;
    }

    public static MetadataDescriptor read(DataInput input) throws IOException {
        MetadataReader r = new MetadataReader(input);
        return r.getDescriptor();
    }

    static void write(List<Type> types, DataOutput output) throws IOException {
        MetadataDescriptor m = new MetadataDescriptor();
        m.locale = Locale.getDefault().toString();
        m.gmtOffset = TimeZone.getDefault().getRawOffset();
        m.types.addAll(types);
        MetadataWriter w = new MetadataWriter(m);
        w.writeBinary(output);
    }

    @Override
    public String toString() {
        return root.toString();
    }
}
