/*
 *  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.harmony.pack200;

import java.io.IOException;
import java.io.OutputStream;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TimeZone;

import org.apache.harmony.pack200.Archive.PackingFile;
import org.apache.harmony.pack200.Archive.SegmentUnit;
import org.objectweb.asm.ClassReader;

/**
 * Bands containing information about files in the pack200 archive and the file
 * contents for non-class-files. Corresponds to the <code>file_bands</code> set
 * of bands described in the specification.
 */
public class FileBands extends BandSet {

    private final CPUTF8[] fileName;
    private int[] file_name;
    private final int[] file_modtime;
    private final long[] file_size;
    private final int[] file_options;
    private final byte[][] file_bits;
    private final List fileList;
    private final PackingOptions options;
    private final CpBands cpBands;

    public FileBands(CpBands cpBands, SegmentHeader segmentHeader,
            PackingOptions options, SegmentUnit segmentUnit, int effort) {
        super(effort, segmentHeader);
        fileList = segmentUnit.getFileList();
        this.options = options;
        this.cpBands = cpBands;
        int size = fileList.size();
        fileName = new CPUTF8[size];
        file_modtime = new int[size];
        file_size = new long[size];
        file_options = new int[size];
        int totalSize = 0;
        file_bits = new byte[size][];
        int archiveModtime = segmentHeader.getArchive_modtime();

        Set classNames = new HashSet();
        for (Iterator iterator = segmentUnit.getClassList().iterator(); iterator
                .hasNext();) {
            ClassReader reader = (ClassReader) iterator.next();
            classNames.add(reader.getClassName());
        }
        CPUTF8 emptyString = cpBands.getCPUtf8("");
        long modtime;
        int latestModtime = Integer.MIN_VALUE;
        boolean isLatest = !PackingOptions.KEEP.equals(options
                .getModificationTime());
        for (int i = 0; i < size; i++) {
            PackingFile packingFile = (PackingFile) fileList.get(i);
            String name = packingFile.getName();
            if (name.endsWith(".class") && !options.isPassFile(name)) {
                file_options[i] |= (1 << 1);
                if (classNames.contains(name.substring(0, name.length() - 6))) {
                    fileName[i] = emptyString;
                } else {
                    fileName[i] = cpBands.getCPUtf8(name);
                }
            } else {
                fileName[i] = cpBands.getCPUtf8(name);
            }
            // set deflate_hint for file element
            if (options.isKeepDeflateHint() && packingFile.isDefalteHint()) {
                file_options[i] |= 0x1;
            }
            byte[] bytes = packingFile.getContents();
            file_size[i] = bytes.length;
            totalSize += file_size[i];

            // update modification time
            modtime = (packingFile.getModtime() + TimeZone.getDefault().getRawOffset()) / 1000L;
            file_modtime[i] = (int) (modtime - archiveModtime);
            if (isLatest && latestModtime < file_modtime[i]) {
                latestModtime = file_modtime[i];
            }

            file_bits[i] = packingFile.getContents();
        }

        if (isLatest) {
            for (int index = 0; index < size; index++) {
                file_modtime[index] = latestModtime;
            }
        }
    }

    /**
     * All input classes for the segment have now been read in, so this method
     * is called so that this class can calculate/complete anything it could not
     * do while classes were being read.
     */
    public void finaliseBands() {
        file_name = new int[fileName.length];
        for (int i = 0; i < file_name.length; i++) {
            if (fileName[i].equals(cpBands.getCPUtf8(""))) {
                PackingFile packingFile = (PackingFile) fileList.get(i);
                String name = packingFile.getName();
                if (options.isPassFile(name)) {
                    fileName[i] = cpBands.getCPUtf8(name);
                    file_options[i] &= (1 << 1) ^ 0xFFFFFFFF;
                }
            }
            file_name[i] = fileName[i].getIndex();
        }
    }

    public void pack(OutputStream out) throws IOException, Pack200Exception {
        PackingUtils.log("Writing file bands...");
        byte[] encodedBand = encodeBandInt("file_name", file_name,
                Codec.UNSIGNED5);
        out.write(encodedBand);
        PackingUtils.log("Wrote " + encodedBand.length
                + " bytes from file_name[" + file_name.length + "]");

        encodedBand = encodeFlags("file_size", file_size, Codec.UNSIGNED5,
                Codec.UNSIGNED5, segmentHeader.have_file_size_hi());
        out.write(encodedBand);
        PackingUtils.log("Wrote " + encodedBand.length
                + " bytes from file_size[" + file_size.length + "]");

        if (segmentHeader.have_file_modtime()) {
            encodedBand = encodeBandInt("file_modtime", file_modtime,
                    Codec.DELTA5);
            out.write(encodedBand);
            PackingUtils.log("Wrote " + encodedBand.length
                    + " bytes from file_modtime[" + file_modtime.length + "]");
        }
        if (segmentHeader.have_file_options()) {
            encodedBand = encodeBandInt("file_options", file_options,
                    Codec.UNSIGNED5);
            out.write(encodedBand);
            PackingUtils.log("Wrote " + encodedBand.length
                    + " bytes from file_options[" + file_options.length + "]");
        }

        encodedBand = encodeBandInt("file_bits", flatten(file_bits),
                Codec.BYTE1);
        out.write(encodedBand);
        PackingUtils.log("Wrote " + encodedBand.length
                + " bytes from file_bits[" + file_bits.length + "]");
    }

    private int[] flatten(byte[][] bytes) {
        int total = 0;
        for (int i = 0; i < bytes.length; i++) {
            total += bytes[i].length;
        }
        int[] band = new int[total];
        int index = 0;
        for (int i = 0; i < bytes.length; i++) {
            for (int j = 0; j < bytes[i].length; j++) {
                band[index++] = bytes[i][j] & 0xFF;
            }
        }
        return band;
    }

}
