/*
 * Copyright 2017 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "bookmaker.h"
#include "SkOSFile.h"
#include "SkOSPath.h"

static void debug_out(int len, const char* data) {
    // convenient place to intercept arbitrary output
    SkDebugf("%.*s", len, data);
}

bool ParserCommon::parseFile(const char* fileOrPath, const char* suffix, OneFile oneFile) {
    if (!sk_isdir(fileOrPath)) {
        if (!this->parseFromFile(fileOrPath)) {
            SkDebugf("failed to parse %s\n", fileOrPath);
            return false;
        }
    } else if (OneFile::kNo == oneFile) {
        SkOSFile::Iter it(fileOrPath, suffix);
        for (SkString file; it.next(&file); ) {
            // FIXME: skip difficult file for now
            if (string::npos != string(file.c_str()).find("SkFontArguments")) {
                continue;
            }
            if (string::npos != string(file.c_str()).find("SkFontStyle")) {
                continue;
            }
            SkString p = SkOSPath::Join(fileOrPath, file.c_str());
            const char* hunk = p.c_str();
            if (!SkStrEndsWith(hunk, suffix)) {
                continue;
            }
            if (!this->parseFromFile(hunk)) {
                SkDebugf("failed to parse %s\n", hunk);
                return false;
            }
        }
    }
    return true;
}

bool ParserCommon::parseStatus(const char* statusFile, const char* suffix, StatusFilter filter) {
    StatusIter iter(statusFile, suffix, filter);
    if (iter.empty()) {
        return false;
    }
    for (string file; iter.next(&file); ) {
        SkString p = SkOSPath::Join(iter.baseDir().c_str(), file.c_str());
        const char* hunk = p.c_str();
        if (!this->parseFromFile(hunk)) {
            SkDebugf("failed to parse %s\n", hunk);
            return false;
        }
    }
    return true;
}

bool ParserCommon::parseSetup(const char* path) {
    sk_sp<SkData> data = SkData::MakeFromFileName(path);
    if (nullptr == data.get()) {
        SkDebugf("%s missing\n", path);
        return false;
    }
    const char* rawText = (const char*) data->data();
    bool hasCR = false;
    size_t dataSize = data->size();
    for (size_t index = 0; index < dataSize; ++index) {
        if ('\r' == rawText[index]) {
            hasCR = true;
            break;
        }
    }
    string name(path);
    if (hasCR) {
        vector<char> lfOnly;
        for (size_t index = 0; index < dataSize; ++index) {
            char ch = rawText[index];
            if ('\r' == rawText[index]) {
                ch = '\n';
                if ('\n' == rawText[index + 1]) {
                    ++index;
                }
            }
            lfOnly.push_back(ch);
        }
        fLFOnly[name] = lfOnly;
        dataSize = lfOnly.size();
        rawText = &fLFOnly[name].front();
    }
    fRawData[name] = data;
    fStart = rawText;
    fLine = rawText;
    fChar = rawText;
    fEnd = rawText + dataSize;
    fFileName = string(path);
    fLineCount = 1;
    return true;
}

bool ParserCommon::writeBlockIndent(int size, const char* data) {
    bool wroteSomething = false;
    while (size && ' ' >= data[size - 1]) {
        --size;
    }
    bool newLine = false;
    while (size) {
        while (size && ' ' > data[0]) {
            ++data;
            --size;
        }
        if (!size) {
            return wroteSomething;
        }
        if (fReturnOnWrite) {
            return true;
        }
        if (newLine) {
            this->lf(1);
        }
        TextParser parser(fFileName, data, data + size, fLineCount);
        const char* lineEnd = parser.strnchr('\n', data + size);
        int len = lineEnd ? (int) (lineEnd - data) : size;
        this->writePending();
        this->indentToColumn(fIndent);
        if (fDebugOut) {
            debug_out(len, data);
        }
        fprintf(fOut, "%.*s", len, data);
        size -= len;
        data += len;
        newLine = true;
        wroteSomething = true;
    }
    return wroteSomething;
}

bool ParserCommon::writeBlockTrim(int size, const char* data) {
    SkASSERT(size >= 0);
    if (!fReturnOnWrite && fOutdentNext) {
        fIndent -= 4;
        fOutdentNext = false;
    }
    while (size && ' ' >= data[0]) {
        ++data;
        --size;
    }
    while (size && ' ' >= data[size - 1]) {
        --size;
    }
    if (size <= 0) {
        if (!fReturnOnWrite) {
            fLastChar = '\0';
        }
        return false;
    }
    if (fReturnOnWrite) {
        return true;
    }
    SkASSERT(size < 16000);
    if (size > 3 && !strncmp("#end", data, 4)) {
        fMaxLF = 1;
    }
    if (this->leadingPunctuation(data, (size_t) size)) {
        fPendingSpace = 0;
    }
    this->writePending();
    if (fDebugOut) {
        debug_out(size, data);
    }
    fprintf(fOut, "%.*s", size, data);
    fWroteSomething = true;
    int added = 0;
    fLastChar = data[size - 1];
    while (size > 0 && '\n' != data[--size]) {
        ++added;
    }
    fColumn = size ? added : fColumn + added;
    fSpaces = 0;
    fLinefeeds = 0;
    fMaxLF = added > 2 && !strncmp("#if", &data[size + (size > 0)], 3) ? 1 : 2;
    if (fOutdentNext) {
        fIndent -= 4;
        fOutdentNext = false;
    }
    return true;
}

void ParserCommon::writePending() {
    SkASSERT(!fReturnOnWrite);
    fPendingLF = SkTMin(fPendingLF, fMaxLF);
    bool wroteLF = false;
    while (fLinefeeds < fPendingLF) {
        if (fDebugOut) {
            SkDebugf("\n");
        }
        fprintf(fOut, "\n");
        ++fLinefeeds;
        wroteLF = true;
    }
    fPendingLF = 0;
    if (wroteLF) {
        SkASSERT(0 == fColumn);
        SkASSERT(fIndent >= fSpaces);
        if (fDebugOut) {
            SkDebugf("%*s", fIndent - fSpaces, "");
        }
        fprintf(fOut, "%*s", fIndent - fSpaces, "");
        fColumn = fIndent;
        fSpaces = fIndent;
    }
    for (int index = 0; index < fPendingSpace; ++index) {
        if (fDebugOut) {
            SkDebugf(" ");
        }
        fprintf(fOut, " ");
        ++fColumn;
    }
    fPendingSpace = 0;
}

void ParserCommon::writeString(const char* str) {
    SkASSERT(!fReturnOnWrite);
    const size_t len = strlen(str);
    SkASSERT(len > 0);
    SkASSERT(' ' < str[0]);
    fLastChar = str[len - 1];
    SkASSERT(' ' < fLastChar);
    SkASSERT(!strchr(str, '\n'));
    if (this->leadingPunctuation(str, strlen(str))) {
        fPendingSpace = 0;
    }
    this->writePending();
    if (fDebugOut) {
        debug_out((int) strlen(str), str);
    }
    fprintf(fOut, "%s", str);
    fColumn += len;
    fSpaces = 0;
    fLinefeeds = 0;
    fMaxLF = 2;
}

char* ParserCommon::ReadToBuffer(string filename, int* size) {
    FILE* file = fopen(filename.c_str(), "rb");
    if (!file) {
        return nullptr;
    }
    fseek(file, 0L, SEEK_END);
    *size = (int) ftell(file);
    rewind(file);
    char* buffer = new char[*size];
    memset(buffer, ' ', *size);
    SkAssertResult(*size == (int)fread(buffer, 1, *size, file));
    fclose(file);
    fflush(file);
    return buffer;
}

char* ParserCommon::FindDateTime(char* buffer, int size) {
    int index = -1;
    int lineCount = 8;
    while (++index < size && ('\n' != buffer[index] || --lineCount))
        ;
    if (lineCount) {
        return nullptr;
    }
    if (strncmp("\n   on 20", &buffer[index], 9)) {
        return nullptr;
    }
    return &buffer[index];
}

bool ParserCommon::writtenFileDiffers(string filename, string readname) {
    int writtenSize, readSize;
    char* written = ReadToBuffer(filename, &writtenSize);
    if (!written) {
        return true;
    }
    char* read = ReadToBuffer(readname, &readSize);
    if (!read) {
        delete[] written;
        return true;
    }
#if 0  // enable for debugging this
    int smaller = SkTMin(writtenSize, readSize);
    for (int index = 0; index < smaller; ++index) {
        if (written[index] != read[index]) {
            SkDebugf("%.*s\n", 40, &written[index]);
            SkDebugf("%.*s\n", 40, &read[index]);
            break;
        }
    }
#endif
    if (readSize != writtenSize) {
        return true;
    }
    // force the date/time to be the same, if present in both
    const char* newDateTime = FindDateTime(written, writtenSize);
    char* oldDateTime = FindDateTime(read, readSize);
    if (newDateTime && oldDateTime) {
        memcpy(oldDateTime, newDateTime, 26);
    }
    bool result = !!memcmp(written, read, writtenSize);
    delete[] written;
    delete[] read;
    return result;
}

StatusIter::StatusIter(const char* statusFile, const char* suffix, StatusFilter filter)
    : fSuffix(suffix)
    , fFilter(filter) {
    if (!this->parseFromFile(statusFile)) {
        return;
    }
}

static const char* block_names[] = {
    "Completed",
    "InProgress",
};

string StatusIter::baseDir() {
    SkASSERT(fStack.back().fObject.isArray());
    SkASSERT(fStack.size() > 2);
    string dir;
    for (unsigned index = 2; index < fStack.size(); ++index) {
        dir += fStack[index].fName;
        if (index < fStack.size() - 1) {
            dir += SkOSPath::SEPARATOR;
        }
    }
    return dir;
}

// FIXME: need to compare fBlockName against fFilter
// need to compare fSuffix against next value returned
bool StatusIter::next(string* str) {
    JsonStatus* status;
    do {
        do {
            if (fStack.empty()) {
                return false;
            }
            status = &fStack.back();
            if (status->fIter != status->fObject.end()) {
                break;
            }
            fStack.pop_back();
        } while (true);
        if (1 == fStack.size()) {
            do {
                StatusFilter blockType = StatusFilter::kUnknown;
                for (unsigned index = 0; index < SK_ARRAY_COUNT(block_names); ++index) {
                    if (status->fIter.key().asString() == block_names[index]) {
                        blockType = (StatusFilter) index;
                        break;
                    }
                }
                if (blockType <= fFilter) {
                    break;
                }
                status->fIter++;
            } while (status->fIter != status->fObject.end());
            if (status->fIter == status->fObject.end()) {
                continue;
            }
        }
        if (!status->fObject.isArray()) {
            SkASSERT(status->fIter != status->fObject.end());
            JsonStatus block = {
                *status->fIter,
                status->fIter->begin(),
                status->fIter.key().asString()
            };
            fStack.emplace_back(block);
            status = &(&fStack.back())[-1];
            status->fIter++;
            status = &fStack.back();
            continue;
        }
        *str = status->fIter->asString();
        status->fIter++;
        if (str->length() - strlen(fSuffix) == str->find(fSuffix)) {
            return true;
        }
    } while (true);
    return true;
}

bool StatusIter::parseFromFile(const char* path) {
    sk_sp<SkData> json(SkData::MakeFromFileName(path));
    if (!json) {
        SkDebugf("file %s:\n", path);
        return this->reportError<bool>("file not readable");
    }
    Json::Reader reader;
    const char* data = (const char*)json->data();
    if (!reader.parse(data, data+json->size(), fRoot)) {
        SkDebugf("file %s:\n", path);
        return this->reportError<bool>("file not parsable");
    }
    JsonStatus block = { fRoot, fRoot.begin(), "" };
    fStack.emplace_back(block);
    return true;
}

void StatusIter::reset() {
    fStack.clear();
}
