/*
 *  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.compress.archivers.zip;

import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.util.HashMap;
import java.util.Map;

/**
 * Static helper functions for robustly encoding filenames in zip files. 
 */
abstract class ZipEncodingHelper {

    /**
     * A class, which holds the high characters of a simple encoding
     * and lazily instantiates a Simple8BitZipEncoding instance in a
     * thread-safe manner.
     */
    private static class SimpleEncodingHolder {

        private final char [] highChars;
        private Simple8BitZipEncoding encoding;

        /**
         * Instantiate a simple encoding holder.
         * 
         * @param highChars The characters for byte codes 128 to 255.
         * 
         * @see Simple8BitZipEncoding#Simple8BitZipEncoding(char[])
         */
        SimpleEncodingHolder(char [] highChars) {
            this.highChars = highChars;
        }

        /**
         * @return The associated {@link Simple8BitZipEncoding}, which
         *         is instantiated if not done so far.
         */
        public synchronized Simple8BitZipEncoding getEncoding() {
            if (this.encoding == null) {
                this.encoding = new Simple8BitZipEncoding(this.highChars);
            }
            return this.encoding;
        }
    }

    private static final Map simpleEncodings;

    static {
        simpleEncodings = new HashMap();

        char[] cp437_high_chars =
            new char[] { 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0,
                         0x00e5, 0x00e7, 0x00ea, 0x00eb, 0x00e8, 0x00ef,
                         0x00ee, 0x00ec, 0x00c4, 0x00c5, 0x00c9, 0x00e6,
                         0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
                         0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5,
                         0x20a7, 0x0192, 0x00e1, 0x00ed, 0x00f3, 0x00fa,
                         0x00f1, 0x00d1, 0x00aa, 0x00ba, 0x00bf, 0x2310,
                         0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
                         0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561,
                         0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557,
                         0x255d, 0x255c, 0x255b, 0x2510, 0x2514, 0x2534,
                         0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f,
                         0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550,
                         0x256c, 0x2567, 0x2568, 0x2564, 0x2565, 0x2559,
                         0x2558, 0x2552, 0x2553, 0x256b, 0x256a, 0x2518,
                         0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
                         0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3,
                         0x00b5, 0x03c4, 0x03a6, 0x0398, 0x03a9, 0x03b4,
                         0x221e, 0x03c6, 0x03b5, 0x2229, 0x2261, 0x00b1,
                         0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248,
                         0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2,
                         0x25a0, 0x00a0 };

        SimpleEncodingHolder cp437 = new SimpleEncodingHolder(cp437_high_chars);

        simpleEncodings.put("CP437",cp437);
        simpleEncodings.put("Cp437",cp437);
        simpleEncodings.put("cp437",cp437);
        simpleEncodings.put("IBM437",cp437);
        simpleEncodings.put("ibm437",cp437);

        char[] cp850_high_chars =
            new char[] { 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0,
                         0x00e5, 0x00e7, 0x00ea, 0x00eb, 0x00e8, 0x00ef,
                         0x00ee, 0x00ec, 0x00c4, 0x00c5, 0x00c9, 0x00e6,
                         0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
                         0x00ff, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8,
                         0x00d7, 0x0192, 0x00e1, 0x00ed, 0x00f3, 0x00fa,
                         0x00f1, 0x00d1, 0x00aa, 0x00ba, 0x00bf, 0x00ae,
                         0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
                         0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00c1,
                         0x00c2, 0x00c0, 0x00a9, 0x2563, 0x2551, 0x2557,
                         0x255d, 0x00a2, 0x00a5, 0x2510, 0x2514, 0x2534,
                         0x252c, 0x251c, 0x2500, 0x253c, 0x00e3, 0x00c3,
                         0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550,
                         0x256c, 0x00a4, 0x00f0, 0x00d0, 0x00ca, 0x00cb,
                         0x00c8, 0x0131, 0x00cd, 0x00ce, 0x00cf, 0x2518,
                         0x250c, 0x2588, 0x2584, 0x00a6, 0x00cc, 0x2580,
                         0x00d3, 0x00df, 0x00d4, 0x00d2, 0x00f5, 0x00d5,
                         0x00b5, 0x00fe, 0x00de, 0x00da, 0x00db, 0x00d9,
                         0x00fd, 0x00dd, 0x00af, 0x00b4, 0x00ad, 0x00b1,
                         0x2017, 0x00be, 0x00b6, 0x00a7, 0x00f7, 0x00b8,
                         0x00b0, 0x00a8, 0x00b7, 0x00b9, 0x00b3, 0x00b2,
                         0x25a0, 0x00a0 };

        SimpleEncodingHolder cp850 = new SimpleEncodingHolder(cp850_high_chars);

        simpleEncodings.put("CP850",cp850);
        simpleEncodings.put("Cp850",cp850);
        simpleEncodings.put("cp850",cp850);
        simpleEncodings.put("IBM850",cp850);
        simpleEncodings.put("ibm850",cp850);
    }

    /**
     * Grow a byte buffer, so it has a minimal capacity or at least
     * the double capacity of the original buffer 
     * 
     * @param b The original buffer.
     * @param newCapacity The minimal requested new capacity.
     * @return A byte buffer <code>r</code> with
     *         <code>r.capacity() = max(b.capacity()*2,newCapacity)</code> and
     *         all the data contained in <code>b</code> copied to the beginning
     *         of <code>r</code>.
     *
     */
    static ByteBuffer growBuffer(ByteBuffer b, int newCapacity) {
        b.limit(b.position());
        b.rewind();

        int c2 = b.capacity() * 2;
        ByteBuffer on = ByteBuffer.allocate(c2 < newCapacity ? newCapacity : c2);

        on.put(b);
        return on;
    }

 
    /**
     * The hexadecimal digits <code>0,...,9,A,...,F</code> encoded as
     * ASCII bytes.
     */
    private static final byte[] HEX_DIGITS =
        new byte [] {
        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41,
        0x42, 0x43, 0x44, 0x45, 0x46
    };

    /**
     * Append <code>%Uxxxx</code> to the given byte buffer.
     * The caller must assure, that <code>bb.remaining()&gt;=6</code>.
     * 
     * @param bb The byte buffer to write to.
     * @param c The character to write.
     */
    static void appendSurrogate(ByteBuffer bb, char c) {

        bb.put((byte) '%');
        bb.put((byte) 'U');

        bb.put(HEX_DIGITS[(c >> 12)&0x0f]);
        bb.put(HEX_DIGITS[(c >> 8)&0x0f]);
        bb.put(HEX_DIGITS[(c >> 4)&0x0f]);
        bb.put(HEX_DIGITS[c & 0x0f]);
    }


    /**
     * name of the encoding UTF-8
     */
    static final String UTF8 = "UTF8";

    /**
     * variant name of the encoding UTF-8 used for comparisions.
     */
    private static final String UTF_DASH_8 = "utf-8";

    /**
     * name of the encoding UTF-8
     */
    static final ZipEncoding UTF8_ZIP_ENCODING = new FallbackZipEncoding(UTF8);

    /**
     * Instantiates a zip encoding.
     * 
     * @param name The name of the zip encoding. Specify <code>null</code> for
     *             the platform's default encoding.
     * @return A zip encoding for the given encoding name.
     */
    static ZipEncoding getZipEncoding(String name) {
 
        // fallback encoding is good enough for utf-8.
        if (isUTF8(name)) {
            return UTF8_ZIP_ENCODING;
        }

        if (name == null) {
            return new FallbackZipEncoding();
        }

        SimpleEncodingHolder h =
            (SimpleEncodingHolder) simpleEncodings.get(name);

        if (h!=null) {
            return h.getEncoding();
        }

        try {

            Charset cs = Charset.forName(name);
            return new NioZipEncoding(cs);

        } catch (UnsupportedCharsetException e) {
            return new FallbackZipEncoding(name);
        }
    }

    /**
     * Whether a given encoding - or the platform's default encoding
     * if the parameter is null - is UTF-8.
     */
    static boolean isUTF8(String encoding) {
        if (encoding == null) {
            // check platform's default encoding
            encoding = System.getProperty("file.encoding");
        }
        return UTF8.equalsIgnoreCase(encoding)
            || UTF_DASH_8.equalsIgnoreCase(encoding);
    }
}
