/*
 * 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 "SkOSFile.h"
#include "SkOSPath.h"

#include "parserCommon.h"

void ParserCommon::checkLineLength(size_t len, const char* str) {
    if (!fWritingIncludes) {
        return;
    }
    int column = fColumn;
    const char* lineStart = str;
    for (size_t index = 0; index < len; ++index) {
        if ('\n' == str[index]) {
            if (column > 100) {
                SkDebugf("> 100 columns in %s line %d\n", fFileName.c_str(), fLinesWritten);
                SkDebugf("%.*s\n", &str[index + 1] - lineStart, lineStart);
                SkDebugf("");  // convenient place to set breakpoints
            }
            fLinesWritten++;
            column = 0;
            lineStart = &str[index + 1];
        } else {
            column++;
        }
    }
}

// change Xxx_Xxx to xxx xxx
string ParserCommon::ConvertRef(const string str, bool first) {
    string substitute;
    for (char c : str) {
        if ('_' == c) {
            c = ' ';
        } else if (isupper(c) && !first) {
            c = tolower(c);
        }
        substitute += c;
        first = false;
    }
    return substitute;
}

void ParserCommon::CopyToFile(string oldFile, string newFile) {
    int bufferSize;
    char* buffer = ParserCommon::ReadToBuffer(newFile, &bufferSize);
    FILE* oldOut = fopen(oldFile.c_str(), "wb");
    if (!oldOut) {
        SkDebugf("could not open file %s\n", oldFile.c_str());
        return;
    }
    fwrite(buffer, 1, bufferSize, oldOut);
    fclose(oldOut);
    remove(newFile.c_str());
}

string ParserCommon::HtmlFileName(string bmhFileName) {
    SkASSERT("docs" == bmhFileName.substr(0, 4));
    SkASSERT('\\' == bmhFileName[4] || '/' == bmhFileName[4]);
    SkASSERT(".bmh" == bmhFileName.substr(bmhFileName.length() - 4));
    string result = bmhFileName.substr(5, bmhFileName.length() - 4 - 5);
    return result;
}

bool ParserCommon::parseFile(const char* fileOrPath, const char* suffix, OneFile oneFile) {
    fRawFilePathDir = string(fileOrPath);
    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) {
    fRawFilePathDir = string(statusFile);
    StatusIter iter(statusFile, suffix, filter);
    if (iter.empty()) {
        return false;
    }
    for (string file; iter.next(&file, nullptr); ) {
        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;
}

void ParserCommon::stringAppend(string& result, char ch) const {
    if (fDebugWriteCodeBlock) {
        SkDebugf("%c", ch);
    }
    result += ch;
}

void ParserCommon::stringAppend(string& result, string str) const {
    string condense;
    char last = result.size() ? result.back() : '\n';
    for (auto c : str) {
        if (' ' == c && ' ' == last) {
            continue;
        }
        condense += c;
        if ('\n' != last || ' ' != c) {
            last = c;
        }
    }
    if (fDebugWriteCodeBlock) {
        SkDebugf("%s", condense.c_str());
    }
    result += condense;
}

void ParserCommon::stringAppend(string& result, const Definition* def) const {
    this->stringAppend(result, string(def->fContentStart, def->length()));
}

bool ParserCommon::writeBlockIndent(int size, const char* data, bool ignoreIdent) {
    bool wroteSomething = false;
    while (size && ' ' >= data[size - 1]) {
        --size;
    }
    bool newLine = false;
    char firstCh = 0;
    while (size) {
        while (size && (' ' > data[0] || (' ' == data[0] && ignoreIdent))) {
            ++data;
            --size;
        }
        if (!size) {
            return wroteSomething;
        }
        if (fReturnOnWrite) {
            return true;
        }
        if (newLine) {
            this->lf(1);
        }
        int indent = fIndent;
        if (!firstCh) {
            firstCh = data[0];
        } else if ('(' == firstCh) {
            indent += 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(indent);
        FPRINTF("%.*s", len, data);
        checkLineLength(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 < 20000);
    if (size > 3 && !strncmp("#end", data, 4)) {
        fMaxLF = 1;
    }
    if (this->leadingPunctuation(data, (size_t) size)) {
        fPendingSpace = 0;
    }
    this->writePending();
    FPRINTF("%.*s", size, data);
    checkLineLength(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");
        checkLineLength(1, "\n");
        ++fLinefeeds;
        wroteLF = true;
    }
    fPendingLF = 0;
    if (wroteLF) {
        SkASSERT(0 == fColumn);
        SkASSERT(fIndent >= fSpaces);
        SkASSERT(fIndent - fSpaces < 80);
        if (fDebugOut) {
            SkDebugf("%*s", fIndent - fSpaces, "");
        }
        fprintf(fOut, "%*s", fIndent - fSpaces, "");
        fColumn = fIndent;
        fSpaces = fIndent;
    }
    SkASSERT(!fWritingIncludes || fColumn + fPendingSpace < 100);
    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();
    FPRINTF("%s", str);
    checkLineLength(strlen(str), 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 = ParserCommon::ReadToBuffer(filename, &writtenSize);
    if (!written) {
        return true;
    }
    char* read = ParserCommon::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().fArray);
    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* strPtr, StatusFilter *filter) {
    string str;
    JsonStatus* status;
    StatusFilter blockType = StatusFilter::kCompleted;
    do {
        do {
            if (fStack.empty()) {
                return false;
            }
            status = &fStack.back();
            if (!status->atEnd()) {
                break;
            }
            fStack.pop_back();
        } while (true);
        if (1 == fStack.size()) {
            do {
                blockType = StatusFilter::kUnknown;
                SkASSERT(status->fObject);
                for (unsigned index = 0; index < SK_ARRAY_COUNT(block_names); ++index) {
                    if (!strcmp(status->fObjectIter->fKey.begin(), block_names[index])) {
                        blockType = (StatusFilter) index;
                        break;
                    }
                }
                if (blockType <= fFilter) {
                    break;
                }
                status->advance();
            } while (!status->atEnd());
            if (status->atEnd()) {
                continue;
            }
        }
        if (!status->fArray) {
            SkASSERT(status->fObjectIter != status->fObject->end());
            JsonStatus block = JsonStatus::Make(status->current(),
                                                status->fObjectIter->fKey.begin(),
                                                blockType);
            fStack.emplace_back(block);
            status = &(&fStack.back())[-1];
            status->advance();
            status = &fStack.back();
            continue;
        }
        if (const skjson::StringValue* sv = status->current()) {
            str = sv->begin();
        } else {
            str = status->current().toString().c_str();
        }
        if (strPtr) {
            *strPtr = str;
        }
        if (filter) {
            *filter = status->fStatusFilter;
        }
        status->advance();
        if (str.length() - strlen(fSuffix) == str.find(fSuffix)) {
            return true;
        }
    } while (true);
    return true;
}

bool JsonCommon::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");
    }
    fDom.reset(new skjson::DOM((const char*)json->data(), json->size()));
    if (!fDom->root().is<skjson::ObjectValue>()) {
        SkDebugf("file %s:\n", path);
        return this->reportError<bool>("file not parsable");
    }
    JsonStatus block = JsonStatus::Make(fDom->root(), "", StatusFilter::kUnknown);
    fStack.emplace_back(block);
    return true;
}
