#include "files.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <fnmatch.h>
#include <string.h>
#include <stdlib.h>

static bool
is_comment_line(const char* p)
{
    while (*p && isspace(*p)) {
        p++;
    }
    return *p == '#';
}

static string
path_append(const string& base, const string& leaf)
{
    string full = base;
    if (base.length() > 0 && leaf.length() > 0) {
        full += '/';
    }
    full += leaf;
    return full;
}

static bool
is_whitespace_line(const char* p)
{
    while (*p) {
        if (!isspace(*p)) {
            return false;
        }
        p++;
    }
    return true;
}

static bool
is_exclude_line(const char* p) {
    while (*p) {
        if (*p == '-') {
            return true;
        }
        else if (isspace(*p)) {
            p++;
        }
        else {
            return false;
        }
    }
    return false;
}

void
split_line(const char* p, vector<string>* out)
{
    const char* q = p;
    enum { WHITE, TEXT, IN_QUOTE } state = WHITE;
    while (*p) {
        if (*p == '#') {
            break;
        }

        switch (state)
        {
            case WHITE:
                if (!isspace(*p)) {
                    q = p;
                    state = (*p == '"') ? IN_QUOTE : TEXT;
                }
                break;
            case IN_QUOTE:
                if (*p == '"') {
                    state = TEXT;
                    break;
                }
                // otherwise fall-through to TEXT case
            case TEXT:
                if (state != IN_QUOTE && isspace(*p)) {
                    if (q != p) {
                        const char* start = q;
                        size_t len = p-q;
                        if (len > 2 && *start == '"' && start[len - 1] == '"') {
                            start++;
                            len -= 2;
                        }
                        out->push_back(string(start, len));
                    }
                    state = WHITE;
                }
                break;
        }
        p++;
    }
    if (state == TEXT) {
        const char* start = q;
        size_t len = p-q;
        if (len > 2 && *start == '"' && start[len - 1] == '"') {
            start++;
            len -= 2;
        }
        out->push_back(string(start, len));
    }
}

static void
add_file(vector<FileRecord>* files, const FileOpType fileOp,
            const string& listFile, int listLine,
            const string& sourceName, const string& outName)
{
    FileRecord rec;
    rec.listFile = listFile;
    rec.listLine = listLine;
    rec.fileOp = fileOp;
    rec.sourceName = sourceName;
    rec.outName = outName;
    files->push_back(rec);
}

static string
replace_variables(const string& input,
                  const map<string, string>& variables,
                  bool* error) {
    if (variables.empty()) {
        return input;
    }

    // Abort if the variable prefix is not found
    if (input.find("${") == string::npos) {
        return input;
    }

    string result = input;

    // Note: rather than be fancy to detect recursive replacements,
    // we simply iterate till a given threshold is met.

    int retries = 1000;
    bool did_replace;

    do {
        did_replace = false;
        for (map<string, string>::const_iterator it = variables.begin();
             it != variables.end(); ++it) {
            string::size_type pos = 0;
            while((pos = result.find(it->first, pos)) != string::npos) {
                result = result.replace(pos, it->first.length(), it->second);
                pos += it->second.length();
                did_replace = true;
            }
        }
        if (did_replace && --retries == 0) {
            *error = true;
            fprintf(stderr, "Recursive replacement detected during variables "
                    "substitution. Full list of variables is: ");

            for (map<string, string>::const_iterator it = variables.begin();
                 it != variables.end(); ++it) {
                fprintf(stderr, "  %s=%s\n",
                        it->first.c_str(), it->second.c_str());
            }

            return result;
        }
    } while (did_replace);

    return result;
}

int
read_list_file(const string& filename,
               const map<string, string>& variables,
               vector<FileRecord>* files,
               vector<string>* excludes)
{
    int err = 0;
    FILE* f = NULL;
    long size;
    char* buf = NULL;
    char *p, *q;
    int i, lineCount;

    f = fopen(filename.c_str(), "r");
    if (f == NULL) {
        fprintf(stderr, "Could not open list file (%s): %s\n",
                    filename.c_str(), strerror(errno));
        err = errno;
        goto cleanup;
    }

    err = fseek(f, 0, SEEK_END);
    if (err != 0) {
        fprintf(stderr, "Could not seek to the end of file %s. (%s)\n",
                    filename.c_str(), strerror(errno));
        err = errno;
        goto cleanup;
    }

    size = ftell(f);

    err = fseek(f, 0, SEEK_SET);
    if (err != 0) {
        fprintf(stderr, "Could not seek to the beginning of file %s. (%s)\n",
                    filename.c_str(), strerror(errno));
        err = errno;
        goto cleanup;
    }

    buf = (char*)malloc(size+1);
    if (buf == NULL) {
        // (potentially large)
        fprintf(stderr, "out of memory (%ld)\n", size);
        err = ENOMEM;
        goto cleanup;
    }

    if (1 != fread(buf, size, 1, f)) {
        fprintf(stderr, "error reading file %s. (%s)\n",
                    filename.c_str(), strerror(errno));
        err = errno;
        goto cleanup;
    }

    // split on lines
    p = buf;
    q = buf+size;
    lineCount = 0;
    while (p<q) {
        if (*p == '\r' || *p == '\n') {
            *p = '\0';
            lineCount++;
        }
        p++;
    }

    // read lines
    p = buf;
    for (i=0; i<lineCount; i++) {
        int len = strlen(p);
        q = p + len + 1;
        if (is_whitespace_line(p) || is_comment_line(p)) {
            ;
        }
        else if (is_exclude_line(p)) {
            while (*p != '-') p++;
            p++;
            excludes->push_back(string(p));
        }
        else {
            vector<string> words;

            split_line(p, &words);

#if 0
            printf("[ ");
            for (size_t k=0; k<words.size(); k++) {
                printf("'%s' ", words[k].c_str());
            }
            printf("]\n");
#endif
            FileOpType op = FILE_OP_COPY;
            string paths[2];
            int pcount = 0;
            string errstr;
            for (vector<string>::iterator it = words.begin(); it != words.end(); ++it) {
                const string& word = *it;
                if (word == "rm") {
                    if (op != FILE_OP_COPY) {
                        errstr = "Error: you can only specifiy 'rm' or 'strip' once per line.";
                        break;
                    }
                    op = FILE_OP_REMOVE;
                } else if (word == "strip") {
                    if (op != FILE_OP_COPY) {
                        errstr = "Error: you can only specifiy 'rm' or 'strip' once per line.";
                        break;
                    }
                    op = FILE_OP_STRIP;
                } else if (pcount < 2) {
                    bool error = false;
                    paths[pcount++] = replace_variables(word, variables, &error);
                    if (error) {
                        err = 1;
                        goto cleanup;
                    }
                } else {
                    errstr = "Error: More than 2 paths per line.";
                    break;
                }
            }

            if (pcount == 0 && !errstr.empty()) {
                errstr = "Error: No path found on line.";
            }

            if (!errstr.empty()) {
                fprintf(stderr, "%s:%d: bad format: %s\n%s\nExpected: [SRC] [rm|strip] DEST\n",
                        filename.c_str(), i+1, p, errstr.c_str());
                err = 1;
            } else {
                if (pcount == 1) {
                    // pattern: [rm|strip] DEST
                    paths[1] = paths[0];
                }

                add_file(files, op, filename, i+1, paths[0], paths[1]);
            }
        }
        p = q;
    }

cleanup:
    if (buf != NULL) {
        free(buf);
    }
    if (f != NULL) {
        fclose(f);
    }
    return err;
}


int
locate(FileRecord* rec, const vector<string>& search)
{
    if (rec->fileOp == FILE_OP_REMOVE) {
        // Don't touch source files when removing a destination.
        rec->sourceMod = 0;
        rec->sourceSize = 0;
        rec->sourceIsDir = false;
        return 0;
    }

    int err;

    for (vector<string>::const_iterator it=search.begin();
                it!=search.end(); it++) {
        string full = path_append(*it, rec->sourceName);
        struct stat st;
        err = stat(full.c_str(), &st);
        if (err == 0) {
            rec->sourceBase = *it;
            rec->sourcePath = full;
            rec->sourceMod = st.st_mtime;
            rec->sourceSize = st.st_size;
            rec->sourceIsDir = S_ISDIR(st.st_mode);
            return 0;
        }
    }

    fprintf(stderr, "%s:%d: couldn't locate source file: %s\n",
                rec->listFile.c_str(), rec->listLine, rec->sourceName.c_str());
    return 1;
}

void
stat_out(const string& base, FileRecord* rec)
{
    rec->outPath = path_append(base, rec->outName);

    int err;
    struct stat st;
    err = stat(rec->outPath.c_str(), &st);
    if (err == 0) {
        rec->outMod = st.st_mtime;
        rec->outSize = st.st_size;
        rec->outIsDir = S_ISDIR(st.st_mode);
    } else {
        rec->outMod = 0;
        rec->outSize = 0;
        rec->outIsDir = false;
    }
}

string
dir_part(const string& filename)
{
    int pos = filename.rfind('/');
    if (pos <= 0) {
        return ".";
    }
    return filename.substr(0, pos);
}

static void
add_more(const string& entry, bool isDir,
         const FileRecord& rec, vector<FileRecord>*more)
{
    FileRecord r;
    r.listFile = rec.listFile;
    r.listLine = rec.listLine;
    r.sourceName = path_append(rec.sourceName, entry);
    r.sourcePath = path_append(rec.sourceBase, r.sourceName);
    struct stat st;
    int err = stat(r.sourcePath.c_str(), &st);
    if (err == 0) {
        r.sourceMod = st.st_mtime;
    }
    r.sourceIsDir = isDir;
    r.outName = path_append(rec.outName, entry);
    more->push_back(r);
}

static bool
matches_excludes(const char* file, const vector<string>& excludes)
{
    for (vector<string>::const_iterator it=excludes.begin();
            it!=excludes.end(); it++) {
        if (0 == fnmatch(it->c_str(), file, FNM_PERIOD)) {
            return true;
        }
    }
    return false;
}

static int
list_dir(const string& path, const FileRecord& rec,
                const vector<string>& excludes,
                vector<FileRecord>* more)
{
    int err;

    string full = path_append(rec.sourceBase, rec.sourceName);
    full = path_append(full, path);

    DIR *d = opendir(full.c_str());
    if (d == NULL) {
        return errno;
    }

    vector<string> dirs;

    struct dirent *ent;
    while (NULL != (ent = readdir(d))) {
        if (0 == strcmp(".", ent->d_name)
                || 0 == strcmp("..", ent->d_name)) {
            continue;
        }
        if (matches_excludes(ent->d_name, excludes)) {
            continue;
        }
        string entry = path_append(path, ent->d_name);
#ifdef HAVE_DIRENT_D_TYPE
		bool is_directory = (ent->d_type == DT_DIR);
#else
	    // If dirent.d_type is missing, then use stat instead
		struct stat stat_buf;
		stat(entry.c_str(), &stat_buf);
		bool is_directory = S_ISDIR(stat_buf.st_mode);
#endif
        add_more(entry, is_directory, rec, more);
        if (is_directory) {
            dirs.push_back(entry);
        }
    }
    closedir(d);

    for (vector<string>::iterator it=dirs.begin(); it!=dirs.end(); it++) {
        list_dir(*it, rec, excludes, more);
    }

    return 0;
}

int
list_dir(const FileRecord& rec, const vector<string>& excludes,
            vector<FileRecord>* files)
{
    return list_dir("", rec, excludes, files);
}

FileRecord::FileRecord() {
    fileOp = FILE_OP_COPY;
}

