/*
 * Copyright 2004-2005 Sun Microsystems, Inc.  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.
 *
 * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

/*
 *
 *
 * Used by BootClassPath.sh.
 *
 * Given a "work directory" this class creates a sub-directory with a
 * name that uses locale specific characters. It the creates a jar
 * manifest file in the work directory with a Boot-Class-Path that
 * encodes the created sub-directory. Finally it creates a file
 * "boot.dir" in the work directory with the name of the sub-directory.
 */
import java.io.File;
import java.io.FileOutputStream;
import java.nio.charset.Charset;

public class Setup {

    public static void main(String[] args) throws Exception {
        if (args.length < 2) {
            System.err.println("Usage: java Setup <work-dir> <premain-class>");
            return;
        }
        String workDir = args[0];
        String premainClass = args[1];

        String manifestFile = workDir + fileSeparator + "MANIFEST.MF";
        String bootClassPath = "boot" + suffix();

        String bootDir = workDir + fileSeparator + bootClassPath;


        /*
         * Create sub-directory
         */
        File f = new File(bootDir);
        f.mkdir();

        /*
         * Create manifest file with Boot-Class-Path encoding the
         * sub-directory name.
         */
        FileOutputStream out = new FileOutputStream(manifestFile);
        out.write("Manifest-Version: 1.0\n".getBytes("UTF-8"));

        byte[] premainBytes = ("Premain-Class: " + premainClass + "\n").getBytes("UTF-8");
        out.write(premainBytes);

        out.write( "Boot-Class-Path: ".getBytes("UTF-8") );

        byte[] value = bootClassPath.getBytes("UTF-8");
        for (int i=0; i<value.length; i++) {
            int v = (int)value[i];
            if (v < 0) v += 256;
            byte[] escaped =  ("%" + Integer.toHexString(v)).getBytes("UTF-8");
            out.write(escaped);
        }
        out.write( "\n\n".getBytes("UTF-8") );
        out.close();

        /*
         * Write the name of the boot dir to "boot.dir"
         */
        f = new File(workDir + fileSeparator + "boot.dir");
        out = new FileOutputStream(f);
        out.write(bootDir.getBytes(defaultEncoding));
        out.close();
    }

    /* ported from test/sun/tools/launcher/UnicodeTest.java */

    private static final String fileSeparator = System.getProperty("file.separator");
    private static final String osName = System.getProperty("os.name");
    private static final String defaultEncoding = Charset.defaultCharset().name();

    // language names taken from java.util.Locale.getDisplayLanguage for the respective language
    private static final String arabic = "\u0627\u0644\u0639\u0631\u0628\u064a\u0629";
    private static final String s_chinese = "\u4e2d\u6587";
    private static final String t_chinese = "\u4e2d\u6587";
    private static final String russian = "\u0440\u0443\u0441\u0441\u043A\u0438\u0439";
    private static final String hindi = "\u0939\u093f\u0902\u0926\u0940";
    private static final String greek = "\u03b5\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac";
    private static final String hebrew = "\u05e2\u05d1\u05e8\u05d9\u05ea";
    private static final String japanese = "\u65e5\u672c\u8a9e";
    private static final String korean = "\ud55c\uad6d\uc5b4";
    private static final String lithuanian = "Lietuvi\u0173";
    private static final String czech = "\u010de\u0161tina";
    private static final String turkish = "T\u00fcrk\u00e7e";
    private static final String spanish = "espa\u00f1ol";
    private static final String thai = "\u0e44\u0e17\u0e22";
    private static final String unicode = arabic + s_chinese + t_chinese
            + russian + hindi + greek + hebrew + japanese + korean
            + lithuanian + czech + turkish + spanish + thai;

    private static String suffix() {

        // Mapping from main platform encodings to language names
        // for Unix and Windows, respectively. Use empty suffix
        // for Windows encodings where OEM encoding differs.
        // Use null if encoding isn't used.
        String[][] names = {
            { "UTF-8",          unicode,        ""              },
            { "windows-1256",   null,           ""              },
            { "iso-8859-6",     arabic,         null            },
            { "GBK",            s_chinese,      s_chinese       },
            { "GB18030",        s_chinese,      s_chinese       },
            { "GB2312",         s_chinese,      null            },
            { "x-windows-950",  null,           t_chinese       },
            { "x-MS950-HKSCS",  null,           t_chinese       },
            { "x-euc-tw",       t_chinese,      null            },
            { "Big5",           t_chinese,      null            },
            { "Big5-HKSCS",     t_chinese,      null            },
            { "windows-1251",   null,           ""              },
            { "iso-8859-5",     russian,        null            },
            { "koi8-r",         russian,        null            },
            { "windows-1253",   null,           ""              },
            { "iso-8859-7",     greek,          null            },
            { "windows-1255",   null,           ""              },
            { "iso8859-8",      hebrew,         null            },
            { "windows-31j",    null,           japanese        },
            { "x-eucJP-Open",   japanese,       null            },
            { "x-EUC-JP-LINUX", japanese,       null            },
            { "x-pck",          japanese,       null            },
            { "x-windows-949",  null,           korean          },
            { "euc-kr",         korean,         null            },
            { "windows-1257",   null,           ""              },
            { "iso-8859-13",    lithuanian,     null            },
            { "windows-1250",   null,           ""              },
            { "iso-8859-2",     czech,          null            },
            { "windows-1254",   null,           ""              },
            { "iso-8859-9",     turkish,        null            },
            { "windows-1252",   null,           ""              },
            { "iso-8859-1",     spanish,        null            },
            { "iso-8859-15",    spanish,        null            },
            { "x-windows-874",  null,           thai            },
            { "tis-620",        thai,           null            },
        };

        int column;
        if (osName.startsWith("Windows")) {
            column = 2;
        } else {
            column = 1;
        }
        for (int i = 0; i < names.length; i++) {
             if (names[i][0].equalsIgnoreCase(defaultEncoding)) {
                 return names[i][column];
             }
         }
         return "";
    }
}
