// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/******************************************************************************
 *   Copyright (C) 2008-2015, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 */
#include "unicode/utypes.h"
#include "unicode/localpointer.h"
#include "unicode/putil.h"
#include "cstring.h"
#include "toolutil.h"
#include "uoptions.h"
#include "uparse.h"
#include "package.h"
#include "pkg_icu.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// read a file list -------------------------------------------------------- ***

U_NAMESPACE_USE

static const struct {
    const char *suffix;
    int32_t length;
} listFileSuffixes[]={
    { ".txt", 4 },
    { ".lst", 4 },
    { ".tmp", 4 }
};

/* check for multiple text file suffixes to see if this list name is a text file name */
static UBool
isListTextFile(const char *listname) {
    const char *listNameEnd=strchr(listname, 0);
    const char *suffix;
    int32_t i, length;
    for(i=0; i<UPRV_LENGTHOF(listFileSuffixes); ++i) {
        suffix=listFileSuffixes[i].suffix;
        length=listFileSuffixes[i].length;
        if((listNameEnd-listname)>length && 0==memcmp(listNameEnd-length, suffix, length)) {
            return TRUE;
        }
    }
    return FALSE;
}

/*
 * Read a file list.
 * If the listname ends with ".txt", then read the list file
 * (in the system/ invariant charset).
 * If the listname ends with ".dat", then read the ICU .dat package file.
 * Otherwise, read the file itself as a single-item list.
 */
U_CAPI Package * U_EXPORT2
readList(const char *filesPath, const char *listname, UBool readContents, Package *listPkgIn) {
    Package *listPkg = listPkgIn;
    FILE *file;
    const char *listNameEnd;

    if(listname==NULL || listname[0]==0) {
        fprintf(stderr, "missing list file\n");
        return NULL;
    }

    if (listPkg == NULL) {
        listPkg=new Package();
        if(listPkg==NULL) {
            fprintf(stderr, "icupkg: not enough memory\n");
            exit(U_MEMORY_ALLOCATION_ERROR);
        }
    }

    listNameEnd=strchr(listname, 0);
    if(isListTextFile(listname)) {
        // read the list file
        char line[1024];
        char *end;
        const char *start;

        file=fopen(listname, "r");
        if(file==NULL) {
            fprintf(stderr, "icupkg: unable to open list file \"%s\"\n", listname);
            delete listPkg;
            exit(U_FILE_ACCESS_ERROR);
        }

        while(fgets(line, sizeof(line), file)) {
            // remove comments
            end=strchr(line, '#');
            if(end!=NULL) {
                *end=0;
            } else {
                // remove trailing CR LF
                end=strchr(line, 0);
                while(line<end && (*(end-1)=='\r' || *(end-1)=='\n')) {
                    *--end=0;
                }
            }

            // check first non-whitespace character and
            // skip empty lines and
            // skip lines starting with reserved characters
            start=u_skipWhitespace(line);
            if(*start==0 || NULL!=strchr(U_PKG_RESERVED_CHARS, *start)) {
                continue;
            }

            // take whitespace-separated items from the line
            for(;;) {
                // find whitespace after the item or the end of the line
                for(end=(char *)start; *end!=0 && *end!=' ' && *end!='\t'; ++end) {}
                if(*end==0) {
                    // this item is the last one on the line
                    end=NULL;
                } else {
                    // the item is terminated by whitespace, terminate it with NUL
                    *end=0;
                }
                if(readContents) {
                    listPkg->addFile(filesPath, start);
                } else {
                    listPkg->addItem(start);
                }

                // find the start of the next item or exit the loop
                if(end==NULL || *(start=u_skipWhitespace(end+1))==0) {
                    break;
                }
            }
        }
        fclose(file);
    } else if((listNameEnd-listname)>4 && 0==memcmp(listNameEnd-4, ".dat", 4)) {
        // read the ICU .dat package
        // Accept a .dat file whose name differs from the ToC prefixes.
        listPkg->setAutoPrefix();
        listPkg->readPackage(listname);
    } else {
        // list the single file itself
        if(readContents) {
            listPkg->addFile(filesPath, listname);
        } else {
            listPkg->addItem(listname);
        }
    }

    return listPkg;
}

U_CAPI int U_EXPORT2
writePackageDatFile(const char *outFilename, const char *outComment, const char *sourcePath, const char *addList, Package *pkg, char outType) {
    LocalPointer<Package> ownedPkg;
    LocalPointer<Package> addListPkg;

    if (pkg == NULL) {
        ownedPkg.adoptInstead(new Package);
        if(ownedPkg.isNull()) {
            fprintf(stderr, "icupkg: not enough memory\n");
            return U_MEMORY_ALLOCATION_ERROR;
        }
        pkg = ownedPkg.getAlias();

        addListPkg.adoptInstead(readList(sourcePath, addList, TRUE, NULL));
        if(addListPkg.isValid()) {
            pkg->addItems(*addListPkg);
        } else {
            return U_ILLEGAL_ARGUMENT_ERROR;
        }
    }

    pkg->writePackage(outFilename, outType, outComment);
    return 0;
}
