/*
 * 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 static jdk.jfr.internal.MetadataDescriptor.ATTRIBUTE_CONSTANT_POOL;
import static jdk.jfr.internal.MetadataDescriptor.ATTRIBUTE_DEFAULT_VALUE;
import static jdk.jfr.internal.MetadataDescriptor.ATTRIBUTE_DIMENSION;
import static jdk.jfr.internal.MetadataDescriptor.ATTRIBUTE_GMT_OFFSET;
import static jdk.jfr.internal.MetadataDescriptor.ATTRIBUTE_ID;
import static jdk.jfr.internal.MetadataDescriptor.ATTRIBUTE_LOCALE;
import static jdk.jfr.internal.MetadataDescriptor.ATTRIBUTE_NAME;
import static jdk.jfr.internal.MetadataDescriptor.ATTRIBUTE_SIMPLE_TYPE;
import static jdk.jfr.internal.MetadataDescriptor.ATTRIBUTE_SUPER_TYPE;
import static jdk.jfr.internal.MetadataDescriptor.ATTRIBUTE_TYPE_ID;
import static jdk.jfr.internal.MetadataDescriptor.ELEMENT_ANNOTATION;
import static jdk.jfr.internal.MetadataDescriptor.ELEMENT_FIELD;
import static jdk.jfr.internal.MetadataDescriptor.ELEMENT_SETTING;
import static jdk.jfr.internal.MetadataDescriptor.ELEMENT_TYPE;

import java.io.DataOutput;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;

import jdk.jfr.AnnotationElement;
import jdk.jfr.SettingDescriptor;
import jdk.jfr.ValueDescriptor;
import jdk.jfr.internal.MetadataDescriptor.Attribute;
import jdk.jfr.internal.MetadataDescriptor.Element;
import jdk.jfr.internal.consumer.RecordingInput;

/**
 * Class responsible for converting a list of types into a format that can be
 * parsed by a client.
 *
 */
final class MetadataWriter {

    private final Element metadata = new Element("metadata");
    private final Element root = new Element("root");

    public MetadataWriter(MetadataDescriptor descriptor) {
        descriptor.getTypes().forEach(type -> makeTypeElement(metadata, type));

        root.add(metadata);
        Element region = new Element("region");
        region.addAttribute(ATTRIBUTE_LOCALE, descriptor.locale);
        region.addAttribute(ATTRIBUTE_GMT_OFFSET, descriptor.gmtOffset);
        root.add(region);
    }

    public void writeBinary(DataOutput output) throws IOException {
        Set<String> stringPool = new HashSet<>(1000);
        // Possible improvement, sort string by how often they occur.
        // and assign low number to the most frequently used.
        buildStringPool(root, stringPool);
        HashMap<String, Integer> lookup = new LinkedHashMap<>(stringPool.size());
        int index = 0;
        int poolSize = stringPool.size();
        writeInt(output, poolSize);
        for (String s : stringPool) {
            lookup.put(s, index);
            writeString(output, s);
            index++;
        }
        write(output, root, lookup);
    }

    private void writeString(DataOutput out, String s) throws IOException {
        if (s == null ) {
            out.writeByte(RecordingInput.STRING_ENCODING_NULL);
            return;
        }
        out.writeByte(RecordingInput.STRING_ENCODING_CHAR_ARRAY); // encoding UTF-16
        int length = s.length();
        writeInt(out, length);
            for (int i = 0; i < length; i++) {
                writeInt(out, s.charAt(i));
            }
    }

    private void writeInt(DataOutput out, int v) throws IOException {

        long s = v & 0xffffffffL;
        if (s < 1 << 7) {
            out.write((byte) (s));
            return;
        }
        out.write((byte) (s | 0x80)); // first byte written
        s >>= 7;
        if (s < 1 << 7) {
            out.write((byte) (s));
            return;
        }
        out.write((byte) (s | 0x80)); // second byte written
        s >>= 7;
        if (s < 1 << 7) {
            out.write((byte) (s));
            return;
        }
        out.write((byte) (s | 0x80)); // third byte written
        s >>= 7;
        if (s < 1 << 7) {
            out.write((byte) (s));
            return;
        }
        s >>= 7;
        out.write((byte) (s));// fourth byte written
    }

    private void buildStringPool(Element element, Set<String> pool) {
        pool.add(element.name);
        for (Attribute a : element.attributes) {
            pool.add(a.name);
            pool.add(a.value);
        }
        for (Element child : element.elements) {
            buildStringPool(child, pool);
        }
    }

    private void write(DataOutput output,Element element, HashMap<String, Integer> lookup) throws IOException {
        writeInt(output, lookup.get(element.name));
        writeInt(output, element.attributes.size());
        for (Attribute a : element.attributes) {
            writeInt(output, lookup.get(a.name));
            writeInt(output, lookup.get(a.value));
        }
        writeInt(output, element.elements.size());
        for (Element child : element.elements) {
            write(output, child, lookup);
        }
    }

    private void makeTypeElement(Element root, Type type) {
        Element element = root.newChild(ELEMENT_TYPE);
        element.addAttribute(ATTRIBUTE_NAME, type.getName());
        String superType = type.getSuperType();
        if (superType != null) {
            element.addAttribute(ATTRIBUTE_SUPER_TYPE, superType);
        }
        if (type.isSimpleType()) {
            element.addAttribute(ATTRIBUTE_SIMPLE_TYPE, true);
        }
        element.addAttribute(ATTRIBUTE_ID, type.getId());
        if (type instanceof PlatformEventType) {
            for (SettingDescriptor v : ((PlatformEventType)type).getSettings()) {
                makeSettingElement(element, v);
            }
        }
        for (ValueDescriptor v : type.getFields()) {
            makeFieldElement(element, v);
        }
        for (AnnotationElement a : type.getAnnotationElements()) {
            makeAnnotation(element, a);
        }
    }

    private void makeSettingElement(Element typeElement, SettingDescriptor s) {
        Element element = typeElement.newChild(ELEMENT_SETTING);
        element.addAttribute(ATTRIBUTE_NAME, s.getName());
        element.addAttribute(ATTRIBUTE_TYPE_ID, s.getTypeId());
        element.addAttribute(ATTRIBUTE_DEFAULT_VALUE, s.getDefaultValue());
        for (AnnotationElement a : s.getAnnotationElements()) {
            makeAnnotation(element, a);
        }
    }

    private void makeFieldElement(Element typeElement, ValueDescriptor v) {
        Element element = typeElement.newChild(ELEMENT_FIELD);
        element.addAttribute(ATTRIBUTE_NAME, v.getName());
        element.addAttribute(ATTRIBUTE_TYPE_ID, v.getTypeId());
        if (v.isArray()) {
            element.addAttribute(ATTRIBUTE_DIMENSION, 1);
        }
        if (PrivateAccess.getInstance().isConstantPool(v)) {
            element.addAttribute(ATTRIBUTE_CONSTANT_POOL, true);
        }
        for (AnnotationElement a : v.getAnnotationElements()) {
            makeAnnotation(element, a);
        }
    }

    private void makeAnnotation(Element entity, AnnotationElement annotation) {
        Element element = entity.newChild(ELEMENT_ANNOTATION);
        element.addAttribute(ATTRIBUTE_TYPE_ID, annotation.getTypeId());
        List<Object> values = annotation.getValues();
        int index = 0;
        for (ValueDescriptor v : annotation.getValueDescriptors()) {
            Object value = values.get(index++);
            if (v.isArray()) {
                element.addArrayAttribute(element, v.getName(), value);
            } else {
                element.addAttribute(v.getName(), value);
            }
        }
    }

}
