/***************************************************************************
 *
 * localedef.cpp
 *
 * $Id$
 *
 ***************************************************************************
 *
 * 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.
 *
 * Copyright 2001-2006 Rogue Wave Software.
 * 
 **************************************************************************/

#include "aliases.h"
#include "def.h"             // for Def
#include "diagnostic.h"      // for issue_diag()
#include "loc_exception.h"   // for loc_exception
#include "path.h"

#include <fstream>        // for ifstream
#include <iostream>       // for cerr
#include <string>         // for string
#include <vector>         // for vector

#include <clocale>        // for setlocale(), LC_XXX
#include <cstdlib>        // for atoi()
#include <cstring>        // for strcmp()


// exit status
#define EXIT_OK       0
#define EXIT_ERRORS   4


// charmaps holds pointers to the character maps being used to generate
// the locales.
static std::vector<Charmap*> charmaps;


static void
print_help_msg ()
{
    static const char msg[] = 
        "NAME\n"
        "\tlocaledef - generate a locale environment\n"
        "\n"
        "SYNOPSIS\n"
        "\tlocaledef [-c][-w[###]][-f charmap_file][-i locale_defintion]\n"
        "\t\tlocale_name\n"
        "\n"
        "\tlocaledef -g [-m creation_list]\n"
        "\t\t[-d output_dir][-r charmap_dir][-s src_dir][--ucs]\n"
        "\n"
        "DESCRIPTION\n"
        "\tThe localedef utility sets up the language environment for the\n"
        "\tnamed locale. localedef reads a locale definition file from\n"
        "\tstandard input or from locale_definition file and creates a\n"
        "\tlocale database with the name specified on the command line.\n"
        "\n"
        "OPTIONS\n"
        "\tThe localedef utility recognizes the following options:\n"
        "\n"
        "\t-c\tCreate output irrespective of warnings.\n"
        "\n"
        "\t-f charmap_file\n"
        "\t\tIf the locale definition uses symbolic names use charmap_file.\n"
        "\n"
        "\t-i locale_definition\n"
        "\t\tUse locale_definition as input, instead of standard input\n"
        "\t\t(default).\n"
        "\n"
        "\t-g\tGenerate all the locales listed in the creation list.\n"
        "\n"
        "\t--ucs\tUse UCS for the internal (wchar_t) encoding."
        "\n"
        "\n\t-m creation_list\n"
        "\t\tSpecify a file that lists what combinations of charmaps and\n"
        "\t\tsource files should be used to create a locale.\n"
        "\n"
        "\t-r charmap_dir\n"
        "\t\tSpecify the directory where the character maps are located.\n"
        "\n"
        "\t-s src_dir\n"
        "\t\tSpecify the directory where the source files are located.\n"
        "\n"
        "\t-d output_dir\n"
        "\t\tSpecify the directory where the generated locale database\n"
        "\t\tfiles should be placed.\n"
        "\n"
        "\t-w\tDisable all warning messages.\n"
        "\n"
        "\t-w###\n"
        "\t\tDisable warning number ###.\n"
        "\n"
        "\t--notes\tEnable notes (informational messages).\n"
        "\t-?\n"
        "\t--help\tPrint out this message.\n";

    std::cout << msg;
}


static void
create_locale (std::string std_src,
               std::string std_cmap, 
               std::string outdir,
               std::string std_locale, 
               bool force_output, bool use_ucs,
               bool no_position, bool link_aliases)
{
    // extract the names of the locale and of the codeset
    std::string lname (std_src);
    std::string cname (std_cmap);

    if (lname.rfind(_RWSTD_PATH_SEP) != std::string::npos)
        lname = lname.substr(lname.rfind(_RWSTD_PATH_SEP) + 1, lname.size());

    if (cname.rfind(_RWSTD_PATH_SEP) != std::string::npos)
        cname = cname.substr(cname.rfind(_RWSTD_PATH_SEP) + 1, cname.size());

    if (lname.find('.') != std::string::npos)
        lname = lname.substr(0, lname.find('.'));
    if (cname.find('.') != std::string::npos)
        cname = cname.substr(0, cname.find('.'));
    
    // the vector of corresponding C locales
    StringVector C_locales;
#ifndef _MSC_VER
    get_same_encoding_C_locale (lname, cname, C_locales);
#endif  // _MSC_VER

    // C library locale using same encoding
    std::string enc_C_locale;

#ifdef _RWSTD_NO_ISO_10646_WCHAR_T
    // the encoding C locale
    enc_C_locale = get_C_encoding_locale (cname);

    // platforms with locale dependant wchar_t encodings need the current 
    // C locale to be set.  If there is no C locale with the same name
    // or that uses the same encoding as the locale we are creating 
    // issue warning
    if (enc_C_locale.empty ()) {
        issue_diag (W_COMPAT, false, 0, "no compatible locale found\n");
    } else
        std::setlocale (LC_ALL, enc_C_locale.c_str ());
        
#endif   // _RWSTD_NO_ISO_10646_WCHAR_T

    // if no charmap is present assume ISO-8859-1
    if (std_cmap.empty ())
        std_cmap = "ISO-8859-1";
        
    // retrieve UTF-8 encoding aliases
    std::string utf8_cname("UTF-8");
    StringVector utf8_aliases;
    get_cname_aliases (utf8_cname, utf8_aliases);

    // is it a UTF-8 encoded locale?
    bool is_utf8 = false;
    StringVector::iterator pos = utf8_aliases.begin();
    for (; pos != utf8_aliases.end (); pos++)
        if (ci_compare (cname, *pos) == 0) {
            is_utf8 = true;
            break;
        }

    // retrieve the charmap/codeset object 
    Charmap* charmap_p = 0;        
    std::vector <Charmap*>::iterator charmaps_it = charmaps.begin();
    for (; charmaps_it != charmaps.end(); charmaps_it++){
        if ((*charmaps_it)->get_full_charmap_name() == std_cmap) {
            charmap_p = *charmaps_it;
            break;
        }
    }

    // if none found, create one and parse the corresponding file
    if (0 == charmap_p) {

        issue_diag (I_STAGE, false, 0,
                    "processing character set description file %s\n",
                    std_cmap.c_str ());

        charmap_p = new Charmap (enc_C_locale.c_str (),
                                 std_cmap.c_str (), 
                                 is_utf8, true, true, use_ucs);
        charmaps.push_back (charmap_p);
    }

    // parse the source definition files
    bool def_error = false;

    issue_diag (I_STAGE, false, 0,
                "processing locale definition file %s\n", std_src.c_str ());

    Def def (std_src.c_str (), (outdir + std_locale).c_str (),
             *charmap_p, no_position);

    try {
        // try to parse the input files
        def.process_input ();
    }
    catch (...) {
        def_error = true;
    }

    // create the locale directory
    std::string locale_dir (outdir + std_locale);

    makedir (locale_dir.c_str ());

    if (def_error) {
        // write out the codecvt database and exit if parsing failed
        def.write_codecvt (locale_dir);
        throw loc_exception ("abort.");
    }

    // no output when it hasn't been forced and warnings were present
    if (!force_output && def.warnings_occurred_) {
        std::cerr << "Warnings occurred - No output produced\n";
        return;
    }

    // and write out the locale categories data
    issue_diag (I_STAGE, false, 0, "generating LC_CTYPE database\n");
    def.write_ctype (locale_dir);

    issue_diag (I_STAGE, false, 0, "generating codeset database\n");
    def.write_codecvt (locale_dir);

    issue_diag (I_STAGE, false, 0, "generating LC_MONETARY database\n");
    def.write_monetary (locale_dir);

    issue_diag (I_STAGE, false, 0, "generating LC_NUMERIC database\n");
    def.write_numeric (locale_dir);

    issue_diag (I_STAGE, false, 0, "generating LC_TIME database\n");
    def.write_time (locale_dir);

    issue_diag (I_STAGE, false, 0, "generating LC_COLLATE database\n");
    def.write_collate (locale_dir);

#ifndef _MSC_VER

    issue_diag (I_STAGE, false, 0, "generating LC_MESSAGES database\n");
    def.write_messages (locale_dir);

#endif  // _MSC_VER

    // no C library locales equivalents 
    if (C_locales.empty ())
        return;

#if !defined (_MSC_VER)

    if (link_aliases == false)
        return;

    // some corresponding C lib locale names where found for this name
    StringVector::iterator it = C_locales.begin ();
    for (; it != C_locales.end (); it++) {
        // check if the name actually exists
        if (*it == std_locale)
            continue;

        // set a symlink with the name of the C lib locale
        // pointing to our locale database
        create_symlink (outdir, std_locale, *it);
    }
#endif  // _MSC_VER
}


static void
generate_locales (const char* map_name, const char* /*alias_name*/,
                  const char* charmap_dir, const char* src_dir,
                  const char* output_dir, bool use_ucs, 
                  bool no_position, bool link_aliases)
{
    std::ifstream f (map_name);

    if (!f) {
        issue_diag (E_OPENRD, true, 0, 
                    "the generation list '%s' "
                    "could not be opened\n", map_name);
        return;
    }

    while (f) {
        std::string s1;
        std::string s2;

        f >> s1 >> s2;
        if (f) {
            std::string lname = s1.substr (0, s1.find('.'));
            std::string cname = s2.substr (0, s2.find('.'));

            // our name for a locale database is <locale>.<codeset>
            std::string std_locale(lname + "." + cname);

            // create the locale database
            std::cout << "creating locale " << std_locale << '\n';
            try { 
                create_locale ((std::string(src_dir) + s1),
                               (std::string(charmap_dir) + s2), 
                               std::string (output_dir), std_locale,
                               true, use_ucs, no_position, link_aliases);

            } 
            catch (const std::ios::failure& error) {
                std::cerr << "I/O exception " << error.what() << '\n';
            } 
            catch (loc_exception& e) {
                std::cerr << "Unable to create locale " << std_locale
                          << " : " << e.what () << '\n';
            } 
            catch (const std::exception& error) {
                std::cerr <<"ERROR: " << error.what() << '\n';
            }
            catch (...) {
                std::cerr << "Unable to create locale " << std_locale 
                          << '\n';
            }
        }
    } 
}


struct ProgramOptions
{
    const char* program_name;
    const char* charmap_name;
    const char* source_name;
    const char* map_file;
    const char* alias_file;
    const char* locale_name;

    std::string charmap_dir;
    std::string src_dir;
    std::string output_dir;
    
    bool gen;
    bool force_output;
    bool use_ucs;
    bool no_position;
    bool link_aliases;
};


static bool
process_command_line (ProgramOptions *opts, int argc, char* argv[])
{
    opts->program_name = argv [0];
    opts->charmap_name = "";
    opts->source_name  = "";
    opts->map_file     = 0;
    opts->alias_file   = 0;
    opts->locale_name  = 0;

    opts->gen          = false;
    opts->force_output = false;
    opts->use_ucs      = false;
    opts->no_position  = false;
    opts->link_aliases = false;

    int i;   // index of command line argument being processed

    for (i = 1; i < argc && '-' == argv [i][0]; ++i) {

        switch (argv [i][1]) {

        case 'f':   // set character set description file name
            if (argv [i + 1])
                opts->charmap_name = argv [++i];
            break;

        case 'i':   // set locale definition file name
            if (argv [i + 1])
                opts->source_name = argv [++i];
            break;

        case 'c':   // create output even if warnings are issued
            opts->force_output = true;
            break;

        case 'g':   // generate more than one locale database
            opts->gen = true;
            break;

        case 'm':
            if (argv [i + 1])
                opts->map_file = argv [++i];
            break;

        case 'a':
            if (argv [i + 1])
                opts->alias_file = argv [++i];
            break;

        case 'r':
            if (argv [i + 1])
                opts->charmap_dir = argv [++i];
            break;

        case 's':
            if (argv [i + 1])
                opts->src_dir = argv [++i];
            break;

        case 'd':
            if (argv [i + 1])
                opts->output_dir = argv [++i];
            break;

        case 'w':   // disable one or all warnings
            if (argv [i][2])
                issue_diag (std::atoi (argv [i] + 2), false, 0, 0);
            else
                issue_diag (W_DISABLE, false, 0, 0);
            break;

        case '?':
            print_help_msg ();
            return false;

        case '-':
            if (0 == std::strcmp (argv [i] + 2, "help")) {
                print_help_msg ();
                return false;
            }

            if (0 == std::strcmp (argv [i] + 2, "ucs")) {
                // --ucs: use UCS as the internal wchar_t encoding
                opts->use_ucs = true;
                break;
            }
            else if (0 == std::strcmp (argv [i] + 2, "no_position")) {
                opts->no_position = true;
                break;
            }
            else if (0 == std::strcmp (argv [i] + 2, "aliases")) {
                opts->link_aliases = true;
                break;
            }
            else if (0 == std::strcmp (argv [i] + 2, "notes")) {
                // --notes: enable informational messages (notes)
                issue_diag (I_ENABLE, false, 0, 0);
                break;
            }
            // fall through

        default:
            issue_diag (E_CMDARG, true, 0, "invalid option %s\n", argv [i]);
        }
    }

    if (opts->gen) {

        bool errors = false;

        // make sure that all the required options are specified
        if (0 == opts->map_file) {
            issue_diag (E_NOARG, true, 0, 
                        "option %s requires a string argument\n", "-m");
        }

        if (opts->charmap_dir.empty ()) {
            issue_diag (E_NOARG, true, 0, 
                        "option %s requires a string argument\n", "-r");
        }

        if (opts->src_dir.empty ()) {
            issue_diag (E_NOARG, true, 0, 
                        "option %s requires a string argument\n", "-s");
        }

        if (opts->output_dir.empty ()) {
            issue_diag (E_NOARG, true, 0, 
                        "option %s requires a string argument\n", "-d");
        }

        // append a slash to the directories if the user didn't
        if (opts->output_dir [opts->output_dir.size () - 1] != _RWSTD_PATH_SEP)
            opts->output_dir += _RWSTD_PATH_SEP;

        if (opts->src_dir [opts->src_dir.size () - 1] != _RWSTD_PATH_SEP)
            opts->src_dir += _RWSTD_PATH_SEP;

        if (opts->charmap_dir [opts->charmap_dir.size () - 1] != _RWSTD_PATH_SEP)
            opts->charmap_dir += _RWSTD_PATH_SEP;
    }

    if (0 == argv [i] && !opts->gen) {
        issue_diag (E_NOARG, true, 0, "missing command line argument\n");
    }

    opts->locale_name = argv [i];

    if (argv [i + 1]) {
        issue_diag (E_XARG, true, 0,
                    "extra command line arguments after %s\n", argv [i]);
    }

    return true;
}


int localedef_main (int argc, char *argv[])
{
    ProgramOptions opts;

    if (!process_command_line (&opts, argc, argv))
        return EXIT_OK;

    if (opts.gen) {
        // create the locale databases as specified in generation list
        generate_locales (opts.map_file, opts.alias_file,
                          opts.charmap_dir.c_str (),
                          opts.src_dir.c_str (),
                          opts.output_dir.c_str (),
                          opts.use_ucs,
                          opts.no_position,
                          opts.link_aliases);
    }
    else {
        assert (0 != opts.locale_name);

        // C++ locale name requested
        std::string std_locale (opts.locale_name);

        // retrieve the output directory if any
        std::string std_outdir ("");

        if (std_locale.rfind (_RWSTD_PATH_SEP) != std::string::npos) {
            std_outdir = 
                std_locale.substr (
                    0, std_locale.rfind (_RWSTD_PATH_SEP) + 1);

            std_locale = 
                std_locale.substr (std_locale.rfind (_RWSTD_PATH_SEP) + 1,
                                   std_locale.size ());
        }

        // create the locale database
        create_locale (opts.source_name, opts.charmap_name,
                       std_outdir, std_locale,
                       opts.force_output, opts.use_ucs,
                       opts.no_position, opts.link_aliases);
    }

    return EXIT_OK;
}


// defined in locale.cpp
int locale_main (int, char*[]);


int main (int argc, char *argv[])
{
    int exit_status = EXIT_OK;

    try {

        if (1 < argc && 0 == std::strcmp (argv [1], "--locale-mode")) {

            // invoked with the special option ""--locale-mode"
            // to act like the locale utility

            // remove argv [1] from command line
            for (int i = 2; argv [i]; ++i)
                argv [i - 1] = argv [i];

            // NULL-terminate argv
            argv [argc - 1] = 0;

            exit_status = locale_main (argc - 1, argv);
        }
        else {
            exit_status = localedef_main (argc, argv);
        }
    }
    catch (const std::ios::failure& error) {
        std::cerr << "Error: I/O exception: " << error.what () << '\n';
        exit_status = EXIT_ERRORS;
    } 
    catch (loc_exception&) {
        exit_status = EXIT_ERRORS;
    } 
    catch (const std::exception& error) {
        std::cerr <<"Error: " << error.what () << '\n';
        exit_status = EXIT_ERRORS;
    }
    catch (...) {
        std::cerr << "Error: unknown exception\n";
        exit_status = EXIT_ERRORS;
    }

    return exit_status;
}
