/*
*******************************************************************************
*
*   Copyright (C) 1999-2012, International Business Machines
*   Corporation and others.  All Rights Reserved.
*
*******************************************************************************
*   file name:  genprops.cpp
*   encoding:   US-ASCII
*   tab size:   8 (not used)
*   indentation:4
*
*   created on: 1999dec08
*   created by: Markus W. Scherer
*
*   This program parses the ppucd.txt preparsed Unicode Character Database file
*   and writes several source and binary files into the ICU source tree.
*/

#include <stdio.h>
#include <stdlib.h>
#include "unicode/utypes.h"
#include "unicode/localpointer.h"
#include "unicode/uniset.h"
#include "unicode/unistr.h"
#include "charstr.h"
#include "genprops.h"
#include "ppucd.h"
#include "toolutil.h"
#include "uoptions.h"

U_NAMESPACE_USE

UBool beVerbose=FALSE;
UBool beQuiet=FALSE;

PropsBuilder::PropsBuilder() {}
PropsBuilder::~PropsBuilder() {}
void PropsBuilder::setUnicodeVersion(const UVersionInfo) {}
void PropsBuilder::setAlgNamesRange(UChar32, UChar32,
                                    const char *, const char *, UErrorCode &) {}
void PropsBuilder::setProps(const UniProps &, const UnicodeSet &, UErrorCode &) {}
void PropsBuilder::build(UErrorCode &) {}
void PropsBuilder::writeCSourceFile(const char *, UErrorCode &) {}
void PropsBuilder::writeBinaryData(const char *, UBool, UErrorCode &) {}

enum {
    HELP_H,
    HELP_QUESTION_MARK,
    VERBOSE,
    QUIET,
    COPYRIGHT
};

/* Keep these values in sync with the above enums */
static UOption options[]={
    UOPTION_HELP_H,
    UOPTION_HELP_QUESTION_MARK,
    UOPTION_VERBOSE,
    UOPTION_QUIET,
    UOPTION_COPYRIGHT
};

extern int
main(int argc, char* argv[]) {
    U_MAIN_INIT_ARGS(argc, argv);
    argc=u_parseArgs(argc, argv, LENGTHOF(options), options);

    /* error handling, printing usage message */
    if(argc<0) {
        fprintf(stderr,
            "error in command line argument \"%s\"\n",
            argv[-argc]);
    }
    if(argc<2 || options[HELP_H].doesOccur || options[HELP_QUESTION_MARK].doesOccur) {
        /*
         * Broken into chunks because the C89 standard says the minimum
         * required supported string length is 509 bytes.
         */
        fprintf(stderr,
            "Usage: %s [-options] path/to/ICU/src/root\n"
            "\n"
            "Reads the preparsed UCD file path/to/ICU/src/root/source/data/unidata/ppucd.txt and\n"
            "writes source and binary data files with the character properties.\n"
            "(UCD=Unicode Character Database)\n"
            "\n",
            argv[0]);
        fprintf(stderr,
            "Options:\n"
            "\t-h or -? or --help  this usage text\n"
            "\t-v or --verbose     verbose output\n"
            "\t-q or --quiet       no output\n"
            "\t-c or --copyright   include a copyright notice\n");
        return argc<2 ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR;
    }

    /* get the options values */
    beVerbose=options[VERBOSE].doesOccur;
    beQuiet=options[QUIET].doesOccur;

    /* initialize */
    IcuToolErrorCode errorCode("genprops");
    LocalPointer<PNamesBuilder> pnamesBuilder(createPNamesBuilder(errorCode));
    LocalPointer<PropsBuilder> corePropsBuilder(createCorePropsBuilder(errorCode));
    LocalPointer<PropsBuilder> bidiPropsBuilder(createBiDiPropsBuilder(errorCode));
    LocalPointer<PropsBuilder> casePropsBuilder(createCasePropsBuilder(errorCode));
    LocalPointer<PropsBuilder> namesPropsBuilder(createNamesPropsBuilder(errorCode));
    if(errorCode.isFailure()) {
        fprintf(stderr, "genprops: unable to create PropsBuilders - %s\n", errorCode.errorName());
        return errorCode.reset();
    }

    CharString icuSrcRoot(argv[1], errorCode);

    CharString icuSource(icuSrcRoot, errorCode);
    icuSource.appendPathPart("source", errorCode);

    CharString icuSourceData(icuSource, errorCode);
    icuSourceData.appendPathPart("data", errorCode);

    CharString ppucdPath(icuSourceData, errorCode);
    ppucdPath.appendPathPart("unidata", errorCode);
    ppucdPath.appendPathPart("ppucd.txt", errorCode);

    PreparsedUCD ppucd(ppucdPath.data(), errorCode);
    if(errorCode.isFailure()) {
        fprintf(stderr, "genprops: unable to open %s - %s\n",
                ppucdPath.data(), errorCode.errorName());
        return errorCode.reset();
    }

    // The PNamesBuilder uses preparsed pnames_data.h.
    pnamesBuilder->build(errorCode);
    if(U_FAILURE(errorCode)) {
        fprintf(stderr, "genprops: PNamesBuilder::build() failed - %s\n",
                errorCode.errorName());
        return errorCode.reset();
    }
    ppucd.setPropertyNames(pnamesBuilder->getPropertyNames());

    PreparsedUCD::LineType lineType;
    UnicodeSet newValues;
    while((lineType=ppucd.readLine(errorCode))!=PreparsedUCD::NO_LINE) {
        if(ppucd.lineHasPropertyValues()) {
            const UniProps *props=ppucd.getProps(newValues, errorCode);
            corePropsBuilder->setProps(*props, newValues, errorCode);
            bidiPropsBuilder->setProps(*props, newValues, errorCode);
            casePropsBuilder->setProps(*props, newValues, errorCode);
            namesPropsBuilder->setProps(*props, newValues, errorCode);
        } else if(lineType==PreparsedUCD::UNICODE_VERSION_LINE) {
            const UVersionInfo &version=ppucd.getUnicodeVersion();
            corePropsBuilder->setUnicodeVersion(version);
            bidiPropsBuilder->setUnicodeVersion(version);
            casePropsBuilder->setUnicodeVersion(version);
            namesPropsBuilder->setUnicodeVersion(version);
        } else if(lineType==PreparsedUCD::ALG_NAMES_RANGE_LINE) {
            UChar32 start, end;
            if(ppucd.getRangeForAlgNames(start, end, errorCode)) {
                const char *type=ppucd.nextField();
                const char *prefix=ppucd.nextField();  // NULL if type==hangul
                namesPropsBuilder->setAlgNamesRange(start, end, type, prefix, errorCode);
            }
        }
        if(errorCode.isFailure()) {
            fprintf(stderr,
                    "genprops: error parsing or setting values from ppucd.txt line %ld - %s\n",
                    (long)ppucd.getLineNumber(), errorCode.errorName());
            return errorCode.reset();
        }
    }

    corePropsBuilder->build(errorCode);
    bidiPropsBuilder->build(errorCode);
    casePropsBuilder->build(errorCode);
    namesPropsBuilder->build(errorCode);
    if(errorCode.isFailure()) {
        fprintf(stderr, "genprops error: failure finalizing the data - %s\n",
                errorCode.errorName());
        return errorCode.reset();
    }

    // Write the files with the generated data.
    CharString sourceCommon(icuSource, errorCode);
    sourceCommon.appendPathPart("common", errorCode);

    CharString sourceDataIn(icuSourceData, errorCode);
    sourceDataIn.appendPathPart("in", errorCode);

    UBool withCopyright=options[COPYRIGHT].doesOccur;

    pnamesBuilder->writeCSourceFile(sourceCommon.data(), errorCode);
    pnamesBuilder->writeBinaryData(sourceDataIn.data(), withCopyright, errorCode);
    corePropsBuilder->writeCSourceFile(sourceCommon.data(), errorCode);
    corePropsBuilder->writeBinaryData(sourceDataIn.data(), withCopyright, errorCode);
    bidiPropsBuilder->writeCSourceFile(sourceCommon.data(), errorCode);
    bidiPropsBuilder->writeBinaryData(sourceDataIn.data(), withCopyright, errorCode);
    casePropsBuilder->writeCSourceFile(sourceCommon.data(), errorCode);
    casePropsBuilder->writeBinaryData(sourceDataIn.data(), withCopyright, errorCode);
    namesPropsBuilder->writeBinaryData(sourceDataIn.data(), withCopyright, errorCode);

    return errorCode;
}

/*
 * Hey, Emacs, please set the following:
 *
 * Local Variables:
 * indent-tabs-mode: nil
 * End:
 *
 */
