/*
 * 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.commons.sanselan.formats.tiff.write;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

import org.apache.commons.sanselan.FormatCompliance;
import org.apache.commons.sanselan.ImageReadException;
import org.apache.commons.sanselan.ImageWriteException;
import org.apache.commons.sanselan.common.BinaryFileFunctions;
import org.apache.commons.sanselan.common.BinaryOutputStream;
import org.apache.commons.sanselan.common.bytesource.ByteSource;
import org.apache.commons.sanselan.common.bytesource.ByteSourceArray;
import org.apache.commons.sanselan.formats.tiff.JpegImageData;
import org.apache.commons.sanselan.formats.tiff.TiffContents;
import org.apache.commons.sanselan.formats.tiff.TiffDirectory;
import org.apache.commons.sanselan.formats.tiff.TiffElement;
import org.apache.commons.sanselan.formats.tiff.TiffField;
import org.apache.commons.sanselan.formats.tiff.TiffImageData;
import org.apache.commons.sanselan.formats.tiff.TiffReader;
import org.apache.commons.sanselan.formats.tiff.constants.ExifTagConstants;
import org.apache.commons.sanselan.util.Debug;

public class TiffImageWriterLossless extends TiffImageWriterBase
{
    private final byte exifBytes[];

    public TiffImageWriterLossless(byte exifBytes[])
    {
        this.exifBytes = exifBytes;
    }

    public TiffImageWriterLossless(int byteOrder, byte exifBytes[])
    {
        super(byteOrder);
        this.exifBytes = exifBytes;
    }

    //    private static class TiffPiece
    //    {
    //        public final int offset;
    //        public final int length;
    //
    //        public TiffPiece(final int offset, final int length)
    //        {
    //            this.offset = offset;
    //            this.length = length;
    //        }
    //    }

    private void dumpElements(List<TiffElement> elements) throws IOException
    {
        //        try
        //        {
        ByteSource byteSource = new ByteSourceArray(exifBytes);

        dumpElements(byteSource, elements);
        //        }
        //        catch (ImageReadException e)
        //        {
        //            throw new ImageWriteException(e.getMessage(), e);
        //        }
    }

    private void dumpElements(ByteSource byteSource, List<TiffElement> elements)
            throws IOException
    {
        int last = TIFF_HEADER_SIZE;
        for (int i = 0; i < elements.size(); i++)
        {
            TiffElement element = elements.get(i);
            if (element.offset > last)
            {
                final int SLICE_SIZE = 32;
                int gepLength = element.offset - last;
                Debug.debug("gap of " + gepLength + " bytes.");
                byte bytes[] = byteSource.getBlock(last, gepLength);
                if (bytes.length > 2 * SLICE_SIZE)
                {
                    Debug.debug("\t" + "head", BinaryFileFunctions.head(bytes,
                            SLICE_SIZE));
                    Debug.debug("\t" + "tail", BinaryFileFunctions.tail(bytes,
                            SLICE_SIZE));
                }
                else
                    Debug.debug("\t" + "bytes", bytes);
            }

            Debug.debug("element[" + i + "]:" + element.getElementDescription()
                    + " (" + element.offset + " + " + element.length + " = "
                    + (element.offset + element.length) + ")");
            if (element instanceof TiffDirectory)
            {
                TiffDirectory dir = (TiffDirectory) element;
                Debug.debug("\t" + "next Directory Offset: "
                        + dir.nextDirectoryOffset);
            }
            last = element.offset + element.length;
        }
        Debug.debug();
    }

    private List<TiffElement> analyzeOldTiff() throws ImageWriteException, IOException
    {
        try
        {
            ByteSource byteSource = new ByteSourceArray(exifBytes);
            Map params = null;
            FormatCompliance formatCompliance = FormatCompliance.getDefault();
            TiffContents contents = new TiffReader(false).readContents(byteSource,
                    params, formatCompliance);

            List<TiffElement> elements = new ArrayList<TiffElement>();
            //            result.add(contents.header); // ?

            List<TiffDirectory> directories = contents.directories;
            for (int d = 0; d < directories.size(); d++)
            {
                TiffDirectory directory = directories.get(d);
                elements.add(directory);

                List<TiffField> fields = directory.getDirectoryEntrys();
                for (int f = 0; f < fields.size(); f++)
                {
                    TiffField field = fields.get(f);
                    if (field.tag == ExifTagConstants.EXIF_TAG_MAKER_NOTE.tag) {
                        // Some maker notes reference values stored
                        // inside the maker note itself
                        // using addresses relative to the beginning
                        // of the TIFF file, making it impossible
                        // to move the note to a different location.
                        // To avoid corrupting these maker notes,
                        // pretend all maker notes are a gap in the file
                        // that must be preserved, so the copy that
                        // will be written later will reference
                        // the old copy's values. Happy days.
                        continue;
                    }
                    TiffElement oversizeValue = field.getOversizeValueElement();
                    if (oversizeValue != null)
                        elements.add(oversizeValue);

                }

                JpegImageData jpegImageData = directory.getJpegImageData();
                if (jpegImageData != null)
                    elements.add(jpegImageData);

                TiffImageData tiffImageData = directory.getTiffImageData();
                if (tiffImageData != null)
                {
                    TiffElement.DataElement data[] = tiffImageData
                            .getImageData();
                    for (int i = 0; i < data.length; i++)
                        elements.add(data[i]);
                }
            }

            Collections.sort(elements, TiffElement.COMPARATOR);

            //            dumpElements(byteSource, elements);

            List<TiffElement> result = new ArrayList<TiffElement>();
            {
                final int TOLERANCE = 3;
                //                int last = TIFF_HEADER_SIZE;
                TiffElement start = null;
                int index = -1;
                for (int i = 0; i < elements.size(); i++)
                {
                    TiffElement element = elements.get(i);
                    int lastElementByte = element.offset + element.length;
                    if (start == null)
                    {
                        start = element;
                        index = lastElementByte;
                    }
                    else if (element.offset - index > TOLERANCE)
                    {
                        result.add(new TiffElement.Stub(start.offset, index
                                - start.offset));
                        start = element;
                        index = lastElementByte;
                    }
                    else
                    {
                        index = lastElementByte;
                    }
                }
                if (null != start)
                    result.add(new TiffElement.Stub(start.offset, index
                            - start.offset));
            }

            //            dumpElements(byteSource, result);

            return result;
        }
        catch (ImageReadException e)
        {
            throw new ImageWriteException(e.getMessage(), e);
        }
    }

    @Override
    public void write(OutputStream os, TiffOutputSet outputSet)
            throws IOException, ImageWriteException
    {
        List<TiffElement> analysis = analyzeOldTiff();
        int oldLength = exifBytes.length;
        if (analysis.size() < 1)
            throw new ImageWriteException("Couldn't analyze old tiff data.");
        else if (analysis.size() == 1)
        {
            TiffElement onlyElement = analysis.get(0);
            //            Debug.debug("onlyElement", onlyElement.getElementDescription());
            if (onlyElement.offset == TIFF_HEADER_SIZE
                    && onlyElement.offset + onlyElement.length
                            + TIFF_HEADER_SIZE == oldLength)
            {
                // no gaps in old data, safe to complete overwrite.
                new TiffImageWriterLossy(byteOrder).write(os, outputSet);
                return;
            }
        }

        //        if (true)
        //            throw new ImageWriteException("hahah");

        //        List directories = outputSet.getDirectories();

        TiffOutputSummary outputSummary = validateDirectories(outputSet);

        List<TiffOutputItem> outputItems = outputSet.getOutputItems(outputSummary);

        int outputLength = updateOffsetsStep(analysis, outputItems);
        //        Debug.debug("outputLength", outputLength);

        outputSummary.updateOffsets(byteOrder);

        writeStep(os, outputSet, analysis, outputItems, outputLength);

    }

    private static final Comparator<TiffElement> ELEMENT_SIZE_COMPARATOR = new Comparator<TiffElement>()
    {
        public int compare(TiffElement e1, TiffElement e2)
        {
            return e1.length - e2.length;
        }
    };

    private static final Comparator<TiffOutputItem> ITEM_SIZE_COMPARATOR = new Comparator<TiffOutputItem>()
    {
        public int compare(TiffOutputItem e1, TiffOutputItem e2)
        {
            return e1.getItemLength() - e2.getItemLength();
        }
    };

    private int updateOffsetsStep(List<TiffElement> analysis, List<TiffOutputItem> outputItems)
    {
        // items we cannot fit into a gap, we shall append to tail.
        int overflowIndex = exifBytes.length;

        // make copy.
        List<TiffElement> unusedElements = new ArrayList<TiffElement>(analysis);

        // should already be in order of offset, but make sure.
        Collections.sort(unusedElements, TiffElement.COMPARATOR);
        Collections.reverse(unusedElements);
        // any items that represent a gap at the end of the exif segment, can be discarded.
        while (unusedElements.size() > 0)
        {
            TiffElement element = unusedElements.get(0);
            int elementEnd = element.offset + element.length;
            if (elementEnd == overflowIndex)
            {
                // discarding a tail element.  should only happen once.
                overflowIndex -= element.length;
                unusedElements.remove(0);
            }
            else
                break;
        }

        Collections.sort(unusedElements, ELEMENT_SIZE_COMPARATOR);
        Collections.reverse(unusedElements);

        //        Debug.debug("unusedElements");
        //        dumpElements(unusedElements);

        // make copy.
        List<TiffOutputItem> unplacedItems = new ArrayList<TiffOutputItem>(outputItems);
        Collections.sort(unplacedItems, ITEM_SIZE_COMPARATOR);
        Collections.reverse(unplacedItems);

        while (unplacedItems.size() > 0)
        {
            // pop off largest unplaced item.
            TiffOutputItem outputItem = unplacedItems.remove(0);
            int outputItemLength = outputItem.getItemLength();
            //            Debug.debug("largest unplaced item: "
            //                    + outputItem.getItemDescription() + " (" + outputItemLength
            //                    + ")");

            // search for the smallest possible element large enough to hold the item.
            TiffElement bestFit = null;
            for (int i = 0; i < unusedElements.size(); i++)
            {
                TiffElement element = unusedElements.get(i);
                if (element.length >= outputItemLength)
                    bestFit = element;
                else
                    break;
            }
            if (null == bestFit)
            {
                // we couldn't place this item.  overflow.
                outputItem.setOffset(overflowIndex);
                overflowIndex += outputItemLength;
            }
            else
            {
                outputItem.setOffset(bestFit.offset);
                unusedElements.remove(bestFit);

                if (bestFit.length > outputItemLength)
                {
                    // not a perfect fit.
                    int excessOffset = bestFit.offset + outputItemLength;
                    int excessLength = bestFit.length - outputItemLength;
                    unusedElements.add(new TiffElement.Stub(excessOffset,
                            excessLength));
                    // make sure the new element is in the correct order.
                    Collections.sort(unusedElements, ELEMENT_SIZE_COMPARATOR);
                    Collections.reverse(unusedElements);
                }
            }
        }

        return overflowIndex;
        //
        //        if (true)
        //            throw new IOException("mew");
        //
        //        //        int offset = TIFF_HEADER_SIZE;
        //        int offset = exifBytes.length;
        //
        //        for (int i = 0; i < outputItems.size(); i++)
        //        {
        //            TiffOutputItem outputItem = (TiffOutputItem) outputItems.get(i);
        //
        //            outputItem.setOffset(offset);
        //            int itemLength = outputItem.getItemLength();
        //            offset += itemLength;
        //
        //            int remainder = imageDataPaddingLength(itemLength);
        //            offset += remainder;
        //        }
    }
    private static class BufferOutputStream extends OutputStream
    {
        private final byte buffer[];
        private int index;

        public BufferOutputStream(final byte[] buffer, final int index)
        {
            this.buffer = buffer;
            this.index = index;
        }

        @Override
        public void write(int b) throws IOException
        {
            if (index >= buffer.length)
                throw new IOException("Buffer overflow.");

            buffer[index++] = (byte) b;
        }

        @Override
        public void write(byte b[], int off, int len) throws IOException
        {
            if (index + len > buffer.length)
                throw new IOException("Buffer overflow.");
            System.arraycopy(b, off, buffer, index, len);
            index += len;
        }
    }

    private void writeStep(OutputStream os, TiffOutputSet outputSet,
            List<TiffElement> analysis, List<TiffOutputItem> outputItems, int outputLength)
            throws IOException, ImageWriteException
    {
        TiffOutputDirectory rootDirectory = outputSet.getRootDirectory();

        byte output[] = new byte[outputLength];

        // copy old data (including maker notes, etc.)
        System.arraycopy(exifBytes, 0, output, 0, Math.min(exifBytes.length,
                output.length));

        //        bos.write(exifBytes, TIFF_HEADER_SIZE, exifBytes.length
        //        - TIFF_HEADER_SIZE);

        {
            BufferOutputStream tos = new BufferOutputStream(output, 0);
            BinaryOutputStream bos = new BinaryOutputStream(tos, byteOrder);
            writeImageFileHeader(bos, rootDirectory.getOffset());
        }

        // zero out the parsed pieces of old exif segment, in case we don't overwrite them.
        for (int i = 0; i < analysis.size(); i++)
        {
            TiffElement element = analysis.get(i);
            for (int j = 0; j < element.length; j++)
            {
                int index = element.offset + j;
                if (index < output.length)
                    output[index] = 0;
            }
        }

        // write in the new items
        for (int i = 0; i < outputItems.size(); i++)
        {
            TiffOutputItem outputItem = outputItems.get(i);

            BufferOutputStream tos = new BufferOutputStream(output, outputItem
                    .getOffset());
            BinaryOutputStream bos = new BinaryOutputStream(tos, byteOrder);
            outputItem.writeItem(bos);
        }

        os.write(output);
    }

}
