/*
 * 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 java.util.jar;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * Reads a JAR file manifest. The specification is here:
 * http://java.sun.com/javase/6/docs/technotes/guides/jar/jar.html
 */
class ManifestReader {
    // There are relatively few unique attribute names,
    // but a manifest might have thousands of entries.
    private final HashMap<String, Attributes.Name> attributeNameCache = new HashMap<String, Attributes.Name>();

    private final UnsafeByteSequence valueBuffer = new UnsafeByteSequence(80);

    private final byte[] buf;

    private final int endOfMainSection;

    private int pos;

    private Attributes.Name name;

    private String value;

    private int consecutiveLineBreaks = 0;

    public ManifestReader(byte[] buf, Attributes main) throws IOException {
        this.buf = buf;
        while (readHeader()) {
            main.put(name, value);
        }
        this.endOfMainSection = pos;
    }

    public void readEntries(Map<String, Attributes> entries, Map<String, Manifest.Chunk> chunks) throws IOException {
        int mark = pos;
        while (readHeader()) {
            if (!Attributes.Name.NAME.equals(name)) {
                throw new IOException("Entry is not named");
            }
            String entryNameValue = value;

            Attributes entry = entries.get(entryNameValue);
            if (entry == null) {
                entry = new Attributes(12);
            }

            while (readHeader()) {
                entry.put(name, value);
            }

            if (chunks != null) {
                if (chunks.get(entryNameValue) != null) {
                    // TODO A bug: there might be several verification chunks for
                    // the same name. I believe they should be used to update
                    // signature in order of appearance; there are two ways to fix
                    // this: either use a list of chunks, or decide on used
                    // signature algorithm in advance and reread the chunks while
                    // updating the signature; for now a defensive error is thrown
                    throw new IOException("A jar verifier does not support more than one entry with the same name");
                }
                chunks.put(entryNameValue, new Manifest.Chunk(mark, pos));
                mark = pos;
            }

            entries.put(entryNameValue, entry);
        }
    }

    public int getEndOfMainSection() {
        return endOfMainSection;
    }

    /**
     * Read a single line from the manifest buffer.
     */
    private boolean readHeader() throws IOException {
        if (consecutiveLineBreaks > 1) {
            // break a section on an empty line
            consecutiveLineBreaks = 0;
            return false;
        }
        readName();
        consecutiveLineBreaks = 0;
        readValue();
        // if the last line break is missed, the line
        // is ignored by the reference implementation
        return consecutiveLineBreaks > 0;
    }

    private void readName() throws IOException {
        int mark = pos;

        while (pos < buf.length) {
            if (buf[pos++] != ':') {
                continue;
            }

            String nameString = new String(buf, mark, pos - mark - 1, StandardCharsets.US_ASCII);

            if (buf[pos++] != ' ') {
                throw new IOException(String.format("Invalid value for attribute '%s'", nameString));
            }

            try {
                name = attributeNameCache.get(nameString);
                if (name == null) {
                    name = new Attributes.Name(nameString);
                    attributeNameCache.put(nameString, name);
                }
            } catch (IllegalArgumentException e) {
                // new Attributes.Name() throws IllegalArgumentException but we declare IOException
                throw new IOException(e.getMessage());
            }
            return;
        }
    }

    private void readValue() throws IOException {
        boolean lastCr = false;
        int mark = pos;
        int last = pos;
        valueBuffer.rewind();
        while (pos < buf.length) {
            byte next = buf[pos++];
            switch (next) {
            case 0:
                throw new IOException("NUL character in a manifest");
            case '\n':
                if (lastCr) {
                    lastCr = false;
                } else {
                    consecutiveLineBreaks++;
                }
                continue;
            case '\r':
                lastCr = true;
                consecutiveLineBreaks++;
                continue;
            case ' ':
                if (consecutiveLineBreaks == 1) {
                    valueBuffer.write(buf, mark, last - mark);
                    mark = pos;
                    consecutiveLineBreaks = 0;
                    continue;
                }
            }

            if (consecutiveLineBreaks >= 1) {
                pos--;
                break;
            }
            last = pos;
        }

        valueBuffer.write(buf, mark, last - mark);
        value = valueBuffer.toString(StandardCharsets.UTF_8);
    }
}
