/*
 * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package build.tools.charsetmapping;

import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Scanner;
import java.util.Formatter;

public class Utils {

    public final static char UNMAPPABLE_DECODING = '\uFFFD';
    public final static int  UNMAPPABLE_ENCODING = 0xFFFD;

    public static class Entry {
        public int bs;   //byte sequence reps
        public int cp;   //Unicode codepoint
        public int cp2;  //CC of composite

        public Entry () {}
        public Entry (int bytes, int cp, int cp2) {
            this.bs = bytes;
            this.cp = cp;
            this.cp2 = cp2;
        }
    }

    public static class Parser {
        static final Pattern basic = Pattern.compile("(?:0x)?(\\p{XDigit}++)\\s++(?:0x)?(\\p{XDigit}++)?\\s*+.*");
        static final int gBS = 1;
        static final int gCP = 2;
        static final int gCP2 = 3;

        BufferedReader reader;
        boolean closed;
        Matcher matcher;
        int gbs, gcp, gcp2;

        public Parser (InputStream in, Pattern p, int gbs, int gcp, int gcp2)
            throws IOException
        {
            this.reader = new BufferedReader(new InputStreamReader(in));
            this.closed = false;
            this.matcher = p.matcher("");
            this.gbs = gbs;
            this.gcp = gcp;
            this.gcp2 = gcp2;
        }

        public Parser (InputStream in, Pattern p) throws IOException {
            this(in, p, gBS, gCP, gCP2);
        }

        public Parser (InputStream in) throws IOException {
            this(in, basic, gBS, gCP, gCP2);
        }

        protected boolean isDirective(String line) {
            return line.startsWith("#");
        }

        protected Entry parse(Matcher matcher, Entry mapping) {
            mapping.bs = Integer.parseInt(matcher.group(gbs), 16);
            mapping.cp = Integer.parseInt(matcher.group(gcp), 16);
            if (gcp2 <= matcher.groupCount() &&
                matcher.group(gcp2) != null)
                mapping.cp2 = Integer.parseInt(matcher.group(gcp2), 16);
            else
                mapping.cp2 = 0;
            return mapping;
        }

        public Entry next() throws Exception {
            return next(new Entry());
        }

        // returns null and closes the input stream if the eof has beenreached.
        public Entry next(Entry mapping) throws Exception {
            if (closed)
                return null;
            String line;
            while ((line = reader.readLine()) != null) {
                if (isDirective(line))
                    continue;
                matcher.reset(line);
                if (!matcher.lookingAt()) {
                    //System.out.println("Missed: " + line);
                    continue;
                }
                return parse(matcher, mapping);
            }
            reader.close();
            closed = true;
            return null;
        }
    }

    public static class Output {
        private Formatter out;

        public Output(Formatter out) {
            this.out = out;
        }

        public void close() {
            out.close();
        }

        private void toChar(String fmt, char c) {
            switch (c) {
            case '\b':
                out.format("\\b"); break;
            case '\t':
                out.format("\\t"); break;
            case '\n':
                out.format("\\n"); break;
            case '\f':
                out.format("\\f"); break;
            case '\r':
                out.format("\\r"); break;
            case '\"':
                out.format("\\\""); break;
            case '\'':
                out.format("\\'"); break;
            case '\\':
                out.format("\\\\"); break;
            default:
                out.format(fmt, c & 0xffff);
            }
        }

        public void format(String fmt, Object ... args) {
            out.format(fmt, args);
        }

        public void format(char[] cc, int off, int end, String closure) {
            while (off < end) {
                out.format("        \"");
                for (int j = 0; j < 8; j++) {
                    if (off == end)
                        break;
                    toChar("\\u%04X", cc[off++]);
                }
                if (off == end)
                    out.format("\" %s%n", closure);
                else
                    out.format("\" + %n");
            }
        }

        public void format(char[] cc, String closure) {
            format(cc, 0, cc.length, closure);
        }

        public void format(char[] db, int b1, int b2Min, int b2Max,
                           String closure)
        {
            char[] cc = new char[b2Max - b2Min + 1];
            int off = 0;
            for (int b2 = b2Min; b2 <= b2Max; b2++) {
                cc[off++] = db[(b1 << 8) | b2];
            }
            format(cc, 0, cc.length, closure);
        }

        public void format(char[] date) {
            int off = 0;
            int end = date.length;
            while (off < end) {
                out.format("        ");
                for (int j = 0; j < 8 && off < end; j++) {
                    toChar("'\\u%04X',", date[off++]);
                }
                out.format("%n");
            }
        }
    }

    public static String getCopyright(File f) throws IOException {
        Scanner s = new Scanner(f, "ISO-8859-1");
        StringBuilder sb = new StringBuilder();
        while (s.hasNextLine()) {
            String ln = s.nextLine();
            sb.append(ln + "\n");
            // assume we have the copyright as the first comment
            if (ln.matches("^\\s\\*\\/$"))
                break;
        }
        s.close();
        return sb.toString();
    }
}
