/* 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.
 */

#include <stdio.h>
#include <process.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>

typedef char bool;
#define false 0
#define true (!false)

bool silent = false;
bool shared = false;
bool export_all = false;
enum mode_t { mCompile, mLink, mInstall };
enum output_type_t { otGeneral, otObject, otProgram, otStaticLibrary, otDynamicLibrary };

#ifdef __EMX__
#  define SHELL_CMD  "sh"
#  define CC         "gcc"
#  define GEN_EXPORTS "emxexp"
#  define DEF2IMPLIB_CMD "emximp"
#  define SHARE_SW   "-Zdll -Zmtd"
#  define USE_OMF true
#  define TRUNCATE_DLL_NAME
#  define DYNAMIC_LIB_EXT "dll"
#  define EXE_EXT ".exe"

#  if USE_OMF
     /* OMF is the native format under OS/2 */
#    define STATIC_LIB_EXT "lib"
#    define OBJECT_EXT     "obj"
#    define LIBRARIAN      "emxomfar -p256"
#  else
     /* but the alternative, a.out, can fork() which is sometimes necessary */
#    define STATIC_LIB_EXT "a"
#    define OBJECT_EXT     "o"
#    define LIBRARIAN      "ar"
#  endif
#endif


typedef struct {
    char *arglist[1024];
    int num_args;
    enum mode_t mode;
    enum output_type_t output_type;
    char *output_name;
    char *stub_name;
    char *tmp_dirs[1024];
    int num_tmp_dirs;
    char *obj_files[1024];
    int num_obj_files;
    char *dep_libs[1024];
    int num_dep_libs;
} cmd_data_t;

void parse_args(int argc, char *argv[], cmd_data_t *cmd_data);
bool parse_long_opt(char *arg, cmd_data_t *cmd_data);
int parse_short_opt(char *arg, cmd_data_t *cmd_data);
bool parse_input_file_name(char *arg, cmd_data_t *cmd_data);
bool parse_output_file_name(char *arg, cmd_data_t *cmd_data);
void post_parse_fixup(cmd_data_t *cmd_data);
void append_depenent_libs(cmd_data_t *cmd_data);
int execute_command(cmd_data_t *cmd_data);
char *shell_esc(const char *str);
void cleanup_tmp_dirs(cmd_data_t *cmd_data);
void generate_def_file(cmd_data_t *cmd_data);
char *nameof(char *fullpath);
char *truncate_dll_name(char *path);
void add_dep_lib(char *lib, cmd_data_t *cmd_data);
void add_lib_dep_libs(char *la_file, cmd_data_t *cmd_data);
void write_dep_libs(FILE *stub_handle, cmd_data_t *cmd_data);


int main(int argc, char *argv[])
{
    int rc;
    cmd_data_t cmd_data;

    memset(&cmd_data, 0, sizeof(cmd_data));
    cmd_data.mode = mCompile;
    cmd_data.output_type = otGeneral;

    parse_args(argc, argv, &cmd_data);
    rc = execute_command(&cmd_data);

    if (rc == 0 && cmd_data.stub_name) {
        FILE *stub_handle = fopen(cmd_data.stub_name, "w");

        if (cmd_data.output_type == otStaticLibrary) {
            write_dep_libs(stub_handle, &cmd_data);
        }

        fclose(stub_handle);
    }

    cleanup_tmp_dirs(&cmd_data);
    return rc;
}



void parse_args(int argc, char *argv[], cmd_data_t *cmd_data)
{
    int a;
    char *arg;
    bool argused;

    for (a=1; a < argc; a++) {
        arg = argv[a];
        argused = false;

        if (arg[0] == '-') {
            if (arg[1] == '-') {
                argused = parse_long_opt(arg + 2, cmd_data);
            } else if (arg[1] == 'o' && a+1 < argc) {
                cmd_data->arglist[cmd_data->num_args++] = arg;
                arg = argv[++a];
                argused = parse_output_file_name(arg, cmd_data);
            } else {
                int num_used = parse_short_opt(arg + 1, cmd_data);
                argused = num_used > 0;

                if (num_used > 1) {
                    a += num_used - 1;
                }
            }
        } else {
            argused = parse_input_file_name(arg, cmd_data);
        }

        if (!argused) {
            cmd_data->arglist[cmd_data->num_args++] = arg;
        }
    }

    post_parse_fixup(cmd_data);

    if (cmd_data->output_type == otProgram || cmd_data->output_type == otDynamicLibrary) {
        append_depenent_libs(cmd_data);
    }
}



bool parse_long_opt(char *arg, cmd_data_t *cmd_data)
{
    char *equal_pos = strchr(arg, '=');
    char var[50];
    char value[500];

    if (equal_pos) {
        strncpy(var, arg, equal_pos - arg);
        var[equal_pos - arg] = 0;
        strcpy(value, equal_pos + 1);
    } else {
        strcpy(var, arg);
    }

    if (strcmp(var, "silent") == 0 || strcmp(var, "quiet") == 0) {
        silent = true;
    } else if (strcmp(var, "mode") == 0) {
        if (strcmp(value, "compile") == 0) {
            cmd_data->mode = mCompile;
            cmd_data->output_type = otObject;
        }

        if (strcmp(value, "link") == 0) {
            cmd_data->mode = mLink;
        }

        if (strcmp(value, "install") == 0) {
            cmd_data->mode = mInstall;
        }
    } else if (strcmp(var, "shared") == 0) {
        shared = true;
    } else if (strcmp(var, "export-all") == 0) {
        export_all = true;
    } else if (strcmp(var, "tag") == 0) {
      /* What's this for? Ignore for now */
    } else {
        return false;
    }

    return true;
}



int parse_short_opt(char *arg, cmd_data_t *cmd_data)
{
    if (strcmp(arg, "export-dynamic") == 0) {
        return 1;
    }

    if (strcmp(arg, "module") == 0) {
        shared = true;
        return 1;
    }

    if (strcmp(arg, "Zexe") == 0) {
        return 1;
    }

    if (strcmp(arg, "avoid-version") == 0) {
        return 1;
    }

    if (strcmp(arg, "prefer-pic") == 0) {
        return 1;
    }

    if (strcmp(arg, "prefer-non-pic") == 0) {
        return 1;
    }

    if (strcmp(arg, "version-info") == 0 ) {
        return 2;
    }

    if (strcmp(arg, "no-install") == 0) {
        return 1;
    }

    if (strcmp(arg, "release") == 0 ) {
        return 2;
    }

    if (strcmp(arg, "export-symbols-regex") == 0) {
        return 2;
    }

    return 0;
}



void parse_la_input_file_name(char *arg, cmd_data_t *cmd_data)
{
    char *name = strrchr(arg, '/');
    char *ext;
    char *newarg;
    int pathlen;

    if (name == NULL) {
        name = strrchr(arg, '\\');

        if (name == NULL) {
            name = arg;
        } else {
            name++;
        }
    } else {
        name++;
    }

    pathlen = name - arg;
    newarg = (char *)malloc(strlen(arg) + 10);
    strcpy(newarg, arg);
    newarg[pathlen] = 0;
    strcat(newarg, ".libs/");

    if (strncmp(name, "lib", 3) == 0) {
        name += 3;
    }

    strcat(newarg, name);
    ext = strrchr(newarg, '.') + 1;

    if (shared && cmd_data->mode == mInstall) {
        strcpy(ext, DYNAMIC_LIB_EXT);
        newarg = truncate_dll_name(newarg);
    } else {
        strcpy(ext, STATIC_LIB_EXT);
    }

    cmd_data->arglist[cmd_data->num_args++] = newarg;
}



bool parse_input_file_name(char *arg, cmd_data_t *cmd_data)
{
    char *ext = strrchr(arg, '.');
    char *name = strrchr(arg, '/');
    char *newarg;

    if (!ext) {
        return false;
    }

    ext++;

    if (name == NULL) {
        name = strrchr(arg, '\\');

        if (name == NULL) {
            name = arg;
        } else {
            name++;
        }
    } else {
        name++;
    }

    if (strcmp(ext, "lo") == 0) {
        newarg = (char *)malloc(strlen(arg) + 10);
        strcpy(newarg, arg);
        strcpy(newarg + (ext - arg), OBJECT_EXT);
        cmd_data->arglist[cmd_data->num_args++] = newarg;
        cmd_data->obj_files[cmd_data->num_obj_files++] = newarg;
        return true;
    }

    if (strcmp(ext, "la") == 0) {
        add_lib_dep_libs(arg, cmd_data);
        parse_la_input_file_name(arg, cmd_data);
        return true;
    }

    if (strcmp(ext, "c") == 0) {
        if (cmd_data->stub_name == NULL) {
            cmd_data->stub_name = (char *)malloc(strlen(arg) + 4);
            strcpy(cmd_data->stub_name, arg);
            strcpy(strrchr(cmd_data->stub_name, '.') + 1, "lo");
        }
    }

    if (strcmp(name, CC) == 0 || strcmp(name, CC EXE_EXT) == 0) {
        if (cmd_data->output_type == otGeneral) {
            cmd_data->output_type = otObject;
        }
    }

    return false;
}



bool parse_output_file_name(char *arg, cmd_data_t *cmd_data)
{
    char *name = strrchr(arg, '/');
    char *ext = strrchr(arg, '.');
    char *newarg = NULL, *newext;

    if (name == NULL) {
        name = strrchr(arg, '\\');

        if (name == NULL) {
            name = arg;
        } else {
            name++;
        }
    } else {
        name++;
    }

    if (!ext || stricmp(ext, EXE_EXT) == 0) {
        cmd_data->output_type = otProgram;
        newarg = (char *)malloc(strlen(arg) + 5);
        strcpy(newarg, arg);

        if (!ext) {
            strcat(newarg, EXE_EXT);
            cmd_data->stub_name = arg;
        }

        cmd_data->arglist[cmd_data->num_args++] = newarg;
        cmd_data->output_name = newarg;
        return true;
    }

    ext++;

    if (strcmp(ext, "exe") == 0) {
        cmd_data->output_type = otProgram;
        cmd_data->output_name = newarg;
        return false;
    }

    if (strcmp(ext, "dll") == 0) {
        cmd_data->output_type = otDynamicLibrary;
        cmd_data->output_name = newarg;
        return false;
    }

    if (strcmp(ext, "la") == 0) {
        cmd_data->stub_name = arg;
        cmd_data->output_type = shared ? otDynamicLibrary : otStaticLibrary;
        newarg = (char *)malloc(strlen(arg) + 10);
        mkdir(".libs", 0);
        strcpy(newarg, ".libs/");

        if (strrchr(arg, '/')) {
          arg = strrchr(arg, '/') + 1;
        }

        if (strncmp(arg, "lib", 3) == 0) {
            arg += 3;
        }

        strcat(newarg, arg);
        newext = strrchr(newarg, '.') + 1;
        strcpy(newext, shared ? DYNAMIC_LIB_EXT : STATIC_LIB_EXT);

#ifdef TRUNCATE_DLL_NAME
        if (shared) {
          newarg = truncate_dll_name(newarg);
        }
#endif

        cmd_data->arglist[cmd_data->num_args++] = newarg;
        cmd_data->output_name = newarg;
        return true;
    }

    if (strcmp(ext, "lo") == 0) {
        cmd_data->stub_name = arg;
        cmd_data->output_type = otObject;
        newarg = (char *)malloc(strlen(arg) + 2);
        strcpy(newarg, arg);
        ext = strrchr(newarg, '.') + 1;
        strcpy(ext, OBJECT_EXT);
        cmd_data->arglist[cmd_data->num_args++] = newarg;
        cmd_data->output_name = newarg;
        return true;
    }

    return false;
}



void post_parse_fixup(cmd_data_t *cmd_data)
{
    int a;
    char *arg;
    char *ext;

    if (cmd_data->output_type == otStaticLibrary && cmd_data->mode == mLink) {
        /* We do a real hatchet job on the args when making a static library
         * removing all compiler switches & any other cruft that ar won't like
         * We also need to explode any libraries listed
         */

        for (a=0; a < cmd_data->num_args; a++) {
            arg = cmd_data->arglist[a];

            if (arg) {
                ext = strrchr(arg, '.');

                if (ext) {
                    ext++;
                }

                if (arg[0] == '-') {
                    cmd_data->arglist[a] = NULL;

                    if (strcmp(arg, "-rpath") == 0 && a+1 < cmd_data->num_args) {
                        cmd_data->arglist[a+1] = NULL;
                    }

                    if (strcmp(arg, "-R") == 0 && a+1 < cmd_data->num_args) {
                        cmd_data->arglist[a+1] = NULL;
                    }

                    if (strcmp(arg, "-version-info") == 0 && a+1 < cmd_data->num_args) {
                        cmd_data->arglist[a+1] = NULL;
                    }

                    if (strcmp(arg, "-Zstack") == 0 && a+1 < cmd_data->num_args) {
                        cmd_data->arglist[a+1] = NULL;
                    }

                    if (strcmp(arg, "-o") == 0) {
                        a++;
                    }

                    if (arg[1] == 'l') {
                        add_dep_lib(arg, cmd_data);
                    }
                }

                if (strcmp(arg, CC) == 0 || strcmp(arg, CC EXE_EXT) == 0) {
                    cmd_data->arglist[a] = LIBRARIAN " cr";
                }

                if (ext) {
                    if (strcmp(ext, "h") == 0 || strcmp(ext, "c") == 0) {
                        /* ignore source files, they don't belong in a library */
                        cmd_data->arglist[a] = NULL;
                    }

                    if (strcmp(ext, STATIC_LIB_EXT) == 0) {
                        cmd_data->arglist[a] = NULL;
                    }
                }
            }
        }
    }

    if (cmd_data->output_type == otDynamicLibrary) {
        for (a=0; a < cmd_data->num_args; a++) {
            arg = cmd_data->arglist[a];

            if (arg) {
                if (strcmp(arg, "-rpath") == 0 && a+1 < cmd_data->num_args) {
                    cmd_data->arglist[a] = NULL;
                    cmd_data->arglist[a+1] = NULL;
                }
            }
        }

        if (export_all) {
            generate_def_file(cmd_data);
        }
    }

    if (cmd_data->output_type == otProgram || cmd_data->output_type == otGeneral) {
        for (a=0; a < cmd_data->num_args; a++) {
            arg = cmd_data->arglist[a];

            if (arg) {
                if (strcmp(arg, "-rpath") == 0 && a+1 < cmd_data->num_args) {
                    cmd_data->arglist[a] = NULL;
                    cmd_data->arglist[a+1] = NULL;
                }
            }
        }
    }

#if USE_OMF
    if (cmd_data->output_type == otObject ||
        cmd_data->output_type == otProgram ||
        cmd_data->output_type == otDynamicLibrary) {
        cmd_data->arglist[cmd_data->num_args++] = "-Zomf";
    }
#endif

    if (shared && (cmd_data->output_type == otObject || cmd_data->output_type == otDynamicLibrary)) {
        cmd_data->arglist[cmd_data->num_args++] = SHARE_SW;
    }
}



void append_depenent_libs(cmd_data_t *cmd_data)
{
    int l;

    for (l = 0; l < cmd_data->num_dep_libs; l++) {
        char *arg = cmd_data->dep_libs[l];
        char *ext = strrchr(arg, '.');

        if (ext && strcmp(ext, ".la") == 0) {
            parse_la_input_file_name(cmd_data->dep_libs[l], cmd_data);
        }
        else {
            cmd_data->arglist[cmd_data->num_args++] = arg;
        }
    }
}



int execute_command(cmd_data_t *cmd_data)
{
    int target = 0;
    char *command;
    int a, total_len = 0;
    char *args[4];

    for (a=0; a < cmd_data->num_args; a++) {
        if (cmd_data->arglist[a]) {
            total_len += strlen(cmd_data->arglist[a]) + 1;
        }
    }

    command = (char *)malloc( total_len );
    command[0] = 0;

    for (a=0; a < cmd_data->num_args; a++) {
        if (cmd_data->arglist[a]) {
            strcat(command, cmd_data->arglist[a]);
            strcat(command, " ");
        }
    }

    command[strlen(command)-1] = 0;

    if (!silent) {
        puts(command);
    }

    cmd_data->num_args = target;
    cmd_data->arglist[cmd_data->num_args] = NULL;
    command = shell_esc(command);

    args[0] = SHELL_CMD;
    args[1] = "-c";
    args[2] = command;
    args[3] = NULL;
    return spawnvp(P_WAIT, args[0], args);
}



char *shell_esc(const char *str)
{
    char *cmd;
    unsigned char *d;
    const unsigned char *s;

    cmd = (char *)malloc(2 * strlen(str) + 1);
    d = (unsigned char *)cmd;
    s = (const unsigned char *)str;

    for (; *s; ++s) {
        if (*s == '"' || *s == '\\') {
            *d++ = '\\';
        }
        *d++ = *s;
    }

    *d = '\0';
    return cmd;
}



void add_dep_lib(char *lib, cmd_data_t *cmd_data)
{
    int l;

    while (isspace(*lib)) {
        lib++;
    }

    if (*lib) {
        for (l = 0; l < cmd_data->num_dep_libs; l++) {
            if (stricmp(cmd_data->dep_libs[l], lib) == 0) {
                return;
            }
        }
    }

    if (*lib) {
        cmd_data->dep_libs[cmd_data->num_dep_libs++] = strdup(lib);
    }
}



void write_dep_libs(FILE *stub_handle, cmd_data_t *cmd_data)
{
    int l;
    char cwd[MAXPATHLEN];

    getwd(cwd);
    fputs("dependency_libs='", stub_handle);

    for (l = 0; l < cmd_data->num_dep_libs; l++) {
        if (l) {
            fputs(" ", stub_handle);
        }

        if (cmd_data->dep_libs[l][0] != '/' && cmd_data->dep_libs[l][0] != '-') {
            fprintf(stub_handle, "%s/%s", cwd, cmd_data->dep_libs[l]);
        }
        else {
            fputs(cmd_data->dep_libs[l], stub_handle);
        }
    }

    fputs("'\n", stub_handle);
}



void add_lib_dep_libs(char *la_file, cmd_data_t *cmd_data)
{
    FILE *hla;
    char line[16384];

    add_dep_lib(la_file, cmd_data);
    hla = fopen(la_file, "r");

    if (hla == NULL) {
        fprintf(stderr, "warning: couldn't open %s\n", la_file);
        return;
    }

    while (fgets(line, sizeof(line), hla) != NULL) {
        char *pos = strchr(line, '=');

        if (pos) {
            *pos = 0;
            pos++;

            if (*pos == '\'') {
                char *end;
                pos++;
                end = strchr(pos, '\'');

                if (end != NULL) {
                    *end = 0;
                }
            }

            if (strcmp(line, "dependency_libs") == 0) {
                while (*pos) {
                    char *end = strchr(pos, ' ');

                    if (end != NULL) {
                        *end = 0;
                    }

                    add_dep_lib(pos, cmd_data);

                    if (end) {
                        pos = end + 1;
                    }
                    else {
                        break;
                    }
                }
            }
        }
    }

    fclose(hla);
}



void cleanup_tmp_dir(char *dirname)
{
    DIR *dir;
    struct dirent *entry;
    char fullname[1024];

    dir = opendir(dirname);

    if (dir == NULL)
        return;

    while ((entry = readdir(dir)) != NULL) {
        if (entry->d_name[0] != '.') {
            strcpy(fullname, dirname);
            strcat(fullname, "/");
            strcat(fullname, entry->d_name);
            remove(fullname);
        }
    }

    rmdir(dirname);
}



void cleanup_tmp_dirs(cmd_data_t *cmd_data)
{
    int d;

    for (d=0; d < cmd_data->num_tmp_dirs; d++) {
        cleanup_tmp_dir(cmd_data->tmp_dirs[d]);
    }
}



void generate_def_file(cmd_data_t *cmd_data)
{
    char def_file[1024];
    char implib_file[1024];
    char *ext;
    FILE *hDef;
    char *export_args[1024];
    int num_export_args = 0;
    char *cmd;
    int cmd_size = 0;
    int a;

    if (cmd_data->output_name) {
        strcpy(def_file, cmd_data->output_name);
        strcat(def_file, ".def");
        hDef = fopen(def_file, "w");

        if (hDef != NULL) {
            fprintf(hDef, "LIBRARY '%s' INITINSTANCE\n", nameof(cmd_data->output_name));
            fprintf(hDef, "DATA NONSHARED\n");
            fprintf(hDef, "EXPORTS\n");
            fclose(hDef);

            for (a=0; a < cmd_data->num_obj_files; a++) {
                cmd_size += strlen(cmd_data->obj_files[a]) + 1;
            }

            cmd_size += strlen(GEN_EXPORTS) + strlen(def_file) + 3;
            cmd = (char *)malloc(cmd_size);
            strcpy(cmd, GEN_EXPORTS);

            for (a=0; a < cmd_data->num_obj_files; a++) {
                strcat(cmd, " ");
                strcat(cmd, cmd_data->obj_files[a] );
            }

            strcat(cmd, ">>");
            strcat(cmd, def_file);
            puts(cmd);
            export_args[num_export_args++] = SHELL_CMD;
            export_args[num_export_args++] = "-c";
            export_args[num_export_args++] = cmd;
            export_args[num_export_args++] = NULL;
            spawnvp(P_WAIT, export_args[0], export_args);
            cmd_data->arglist[cmd_data->num_args++] = strdup(def_file);

            /* Now make an import library for the dll */
            num_export_args = 0;
            export_args[num_export_args++] = DEF2IMPLIB_CMD;
            export_args[num_export_args++] = "-o";

            strcpy(implib_file, ".libs/");
            strcat(implib_file, cmd_data->stub_name);
            ext = strrchr(implib_file, '.');

            if (ext)
                *ext = 0;

            strcat(implib_file, ".");
            strcat(implib_file, STATIC_LIB_EXT);

            export_args[num_export_args++] = implib_file;
            export_args[num_export_args++] = def_file;
            export_args[num_export_args++] = NULL;
            spawnvp(P_WAIT, export_args[0], export_args);
        }
    }
}



/* returns just a file's name without path or extension */
char *nameof(char *fullpath)
{
    char buffer[1024];
    char *ext;
    char *name = strrchr(fullpath, '/');

    if (name == NULL) {
        name = strrchr(fullpath, '\\');
    }

    if (name == NULL) {
        name = fullpath;
    } else {
        name++;
    }

    strcpy(buffer, name);
    ext = strrchr(buffer, '.');

    if (ext) {
        *ext = 0;
        return strdup(buffer);
    }

    return name;
}



char *truncate_dll_name(char *path)
{
    /* Cut DLL name down to 8 characters after removing any mod_ prefix */
    char *tmppath = strdup(path);
    char *newname = strrchr(tmppath, '/') + 1;
    char *ext = strrchr(tmppath, '.');
    int len;

    if (ext == NULL)
        return tmppath;

    len = ext - newname;

    if (strncmp(newname, "mod_", 4) == 0) {
        strcpy(newname, newname + 4);
        len -= 4;
    }

    if (len > 8) {
        strcpy(newname + 8, strchr(newname, '.'));
    }

    return tmppath;
}
