/* ====================================================================
   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.poi.hdgf.chunks;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.LocaleUtil;

import static org.apache.logging.log4j.util.Unbox.box;

/**
 * Factor class to create the appropriate chunks, which
 *  needs the version of the file to process the chunk header
 *  and trailer areas.
 * Makes use of chunks_parse_cmds.tbl from vsdump to be able
 *  to process the chunk value area
 */
public final class ChunkFactory {

    //arbitrarily selected; may need to increase
    private static final int MAX_RECORD_LENGTH = 1_000_000;


    /** The version of the currently open document */
    private int version;
    /**
     * Key is a Chunk's type, value is an array of its CommandDefinitions
     */
    private final Map<Integer, CommandDefinition[]> chunkCommandDefinitions =
            new HashMap<>();
    /**
     * What the name is of the chunk table definitions file?
     * This file comes from the scratchpad resources directory.
     */
    private static final String chunkTableName =
        "/org/apache/poi/hdgf/chunks_parse_cmds.tbl";

    /** For logging problems we spot with the file */
    private static final Logger LOG = LogManager.getLogger(ChunkFactory.class);

    public ChunkFactory(int version) throws IOException {
        this.version = version;

        processChunkParseCommands();
    }

    /**
     * Open chunks_parse_cmds.tbl and process it, to get the definitions
     *  of all the different possible chunk commands.
     */
    private void processChunkParseCommands() throws IOException {
        try (InputStream cpd = ChunkFactory.class.getResourceAsStream(chunkTableName)) {
            if(cpd == null) {
                throw new IllegalStateException("Unable to find HDGF chunk definition on the classpath - " + chunkTableName);
            }

            try (BufferedReader inp = new BufferedReader(new InputStreamReader(cpd, LocaleUtil.CHARSET_1252))) {
                String line;
                while ((line = inp.readLine()) != null) {
                    if (line.isEmpty() || "# \t".contains(line.substring(0, 1))) {
                        continue;
                    }

                    // Start xxx
                    if (!line.matches("^start [0-9]+$")) {
                        throw new IllegalStateException("Expecting start xxx, found " + line);
                    }
                    int chunkType = Integer.parseInt(line.substring(6));
                    ArrayList<CommandDefinition> defsL = new ArrayList<>();

                    // Data entries
                    while ((line = inp.readLine()) != null) {
                        if (line.startsWith("end")) {
                            break;
                        }
                        StringTokenizer st = new StringTokenizer(line, " ");
                        int defType = Integer.parseInt(st.nextToken());
                        int offset = Integer.parseInt(st.nextToken());
                        String name = st.nextToken("\uffff").substring(1);

                        CommandDefinition def = new CommandDefinition(defType, offset, name);
                        defsL.add(def);
                    }

                    CommandDefinition[] defs = defsL.toArray(new CommandDefinition[0]);

                    // Add to the map
                    chunkCommandDefinitions.put(chunkType, defs);
                }
            }
        }
    }

    public int getVersion() { return version; }

    /**
     * Creates the appropriate chunk at the given location.
     *
     * @param data the chunk bytes
     * @param offset the offset into the chunk bytes array to start reading from
     *
     * @return the new Chunk
     */
    public Chunk createChunk(byte[] data, int offset) {
        // Create the header
        ChunkHeader header =
            ChunkHeader.createChunkHeader(version, data, offset);
        // Sanity check
        if(header.getLength() < 0) {
            throw new IllegalArgumentException("Found a chunk with a negative length, which isn't allowed");
        }

        // How far up to look
        int endOfDataPos = offset + header.getLength() + header.getSizeInBytes();

        // Check we have enough data, and tweak the header size
        //  as required
        if(endOfDataPos > data.length) {
            LOG.atWarn().log("Header called for {} bytes, but that would take us past the end of the data!", box(header.getLength()));

            endOfDataPos = data.length;
            header.setLength(data.length - offset - header.getSizeInBytes());

            if(header.hasTrailer()) {
                header.setLength(header.getLength() - 8);
                endOfDataPos  -= 8;
            }
            if(header.hasSeparator()) {
                header.setLength(header.getLength() - 4);
                endOfDataPos  -= 4;
            }
        }


        // Create the trailer and separator, if required
        ChunkTrailer trailer = null;
        ChunkSeparator separator = null;
        if(header.hasTrailer()) {
            if(endOfDataPos <= data.length-8) {
                trailer = new ChunkTrailer(
                    data, endOfDataPos);
                endOfDataPos += 8;
            } else {
                LOG.atError().log("Header claims a length to {} there's then no space for the trailer in the data ({})", box(endOfDataPos),box(data.length));
            }
        }
        if(header.hasSeparator()) {
            if(endOfDataPos <= data.length-4) {
                separator = new ChunkSeparator(
                        data, endOfDataPos);
            } else {
                LOG.atError().log("Header claims a length to {} there's then no space for the separator in the data ({})", box(endOfDataPos),box(data.length));
            }
        }

        // Now, create the chunk
        byte[] contents = IOUtils.safelyClone(data, offset+header.getSizeInBytes(), header.getLength(), MAX_RECORD_LENGTH);
        Chunk chunk = new Chunk(header, trailer, separator, contents);

        // Feed in the stuff from  chunks_parse_cmds.tbl
        CommandDefinition[] defs = chunkCommandDefinitions.get(header.getType());
        if (defs == null) {
            defs = new CommandDefinition[0];
        }
        chunk.setCommandDefinitions(defs);

        // Now get the chunk to process its commands
        chunk.processCommands();

        // All done
        return chunk;
    }

    /**
     * The definition of a Command, which a chunk may hold.
     * The Command holds the value, this describes it.
     */
    public static class CommandDefinition {
        private int type;
        private int offset;
        private String name;
        public CommandDefinition(int type, int offset, String name) {
            this.type = type;
            this.offset = offset;
            this.name = name;
        }

        public String getName() {
            return name;
        }
        public int getOffset() {
            return offset;
        }
        public int getType() {
            return type;
        }
    }
}
