/*
 * 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.felix.scr.impl.metadata;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class MetadataStoreHelper
{
    // The version of the component metadata store.  If the
    // stored metadata is not this version then the cache is ignored
    static final int STORE_VERSION = 1;

    static final byte STRING_NULL = 0;
    static final byte STRING_OBJECT = 1;
    static final byte STRING_INDEX = 2;
    static final byte STRING_LONG = 3;

    public static class MetaDataReader
    {
        private final List<String> stringTable = new ArrayList<String>();

        public boolean isVersionSupported(DataInputStream in) throws IOException
        {
            return STORE_VERSION == in.readInt();
        }

        public String readIndexedString(DataInputStream in) throws IOException
        {
            String s = readString(in);
            addToStringTable(s, in.readInt());
            return s;
        }

        public String readString(DataInputStream in) throws IOException
        {
            byte type = in.readByte();
            if (type == STRING_INDEX)
            {
                int index = in.readInt();
                return (String) stringTable.get(index);
            }
            if (type == STRING_NULL)
            {
                return null;
            }
            String s;
            if (type == STRING_LONG)
            {
                int length = in.readInt();
                byte[] data = new byte[length];
                in.readFully(data);
                s = new String(data, "UTF-8");
            }
            else
            {
                s = in.readUTF();
            }
            return s;
        }

        private void addToStringTable(String s, int index)
        {
            if (index == stringTable.size())
            {
                stringTable.add(s);
            }
            else if (index < stringTable.size())
            {
                stringTable.set(index, s);
            }
            else
            {
                while (stringTable.size() < index)
                {
                    stringTable.add(null);
                }
                stringTable.add(s);
            }
        }
    }

    public static class MetaDataWriter
    {
        private final Map<String, Integer> stringTable = new HashMap<>();

        public void writeVersion(DataOutputStream out) throws IOException
        {
            out.writeInt(STORE_VERSION);
        }

        public void writeIndexedString(String s, DataOutputStream out) throws IOException
        {
            writeString(s, out);
            out.writeInt(addToStringTable(s));
        }

        public void writeString(String s, DataOutputStream out) throws IOException
        {
            Integer index = s != null ? stringTable.get(s) : null;
            if (index != null)
            {
                out.writeByte(STRING_INDEX);
                out.writeInt(index);
                return;
            }

            if (s == null)
                out.writeByte(STRING_NULL);
            else
            {
                byte[] data = s.getBytes("UTF-8");

                if (data.length > 65535)
                {
                    out.writeByte(STRING_LONG);
                    out.writeInt(data.length);
                    out.write(data);
                }
                else
                {
                    out.writeByte(STRING_OBJECT);
                    out.writeUTF(s);
                }
            }
        }

        private int addToStringTable(String s)
        {
            if (s == null)
            {
                throw new NullPointerException();
            }
            Integer cur = stringTable.get(s);
            if (cur != null)
                throw new IllegalStateException(
                    "String is already in the write table: " + s);
            int index = stringTable.size();
            stringTable.put(s, Integer.valueOf(index));
            // return the index of the object just added
            return index;
        }
    }

    public static void addString(String s, Set<String> strings)
    {
        if (s != null)
        {
            strings.add(s);
        }
    }
}
