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

static Definition* find_fiddle(Definition* def, const string& name) {
    if (MarkType::kExample == def->fMarkType && name == def->fFiddle) {
        return def;
    }
    for (auto& child : def->fChildren) {
        Definition* result = find_fiddle(child, name);
        if (result) {
            return result;
        }
    }
    return nullptr;
}

Definition* FiddleBase::findExample(const string& name) const {
    for (const auto& topic : fBmhParser->fTopicMap) {
        if (topic.second->fParent) {
            continue;
        }
        Definition* def = find_fiddle(topic.second, name);
        if (def) {
            return def;
        }
    }
    return nullptr;
}

bool FiddleBase::parseFiddles() {
    if (!this->skipExact("{\n")) {
        return false;
    }
    while (!this->eof()) {
        if (!this->skipExact("  \"")) {
            return false;
        }
        const char* nameLoc = fChar;
        if (!this->skipToEndBracket("\"")) {
            return false;
        }
        string name(nameLoc, fChar - nameLoc);
        if (!this->skipExact("\": {\n")) {
            return false;
        }
        if (!this->skipExact("    \"compile_errors\": [")) {
            return false;
        }
        if (']' != this->peek()) {
            // report compiler errors
            int brackets = 1;
            do {
                if ('[' == this->peek()) {
                    ++brackets;
                } else if (']' == this->peek()) {
                    --brackets;
                }
            } while (!this->eof() && this->next() && brackets > 0);
            this->reportError("fiddle compile error");
        }
        if (!this->skipExact("],\n")) {
            return false;
        }
        if (!this->skipExact("    \"runtime_error\": \"")) {
            return false;
        }
        if ('"' != this->peek()) {
            if (!this->skipToEndBracket('"')) {
                return false;
            }
            this->reportError("fiddle runtime error");
        }
        if (!this->skipExact("\",\n")) {
            return false;
        }
        if (!this->skipExact("    \"fiddleHash\": \"")) {
            return false;
        }
        const char* hashStart = fChar;
        if (!this->skipToEndBracket('"')) {
            return false;
        }
        Definition* example = this->findExample(name);
        if (!example) {
            this->reportError("missing example");
        }
        string hash(hashStart, fChar - hashStart);
        if (example) {
            example->fHash = hash;
        }
        if (!this->skipExact("\",\n")) {
            return false;
        }
        if (!this->skipExact("    \"text\": \"")) {
            return false;
        }
        if ('"' != this->peek()) {
            const char* stdOutStart = fChar;
            do {
                if ('\\' == this->peek()) {
                    this->next();
                } else if ('"' == this->peek()) {
                    break;
                }
            } while (!this->eof() && this->next());
            const char* stdOutEnd = fChar;
            if (example && fTextOut) {
                if (!this->textOut(example, stdOutStart, stdOutEnd)) {
                    return false;
                }
            }
        } else {
            if (example && fPngOut) {
                if (!this->pngOut(example)) {
                    return false;
                }
            }
        }
        if (!this->skipExact("\"\n")) {
            return false;
        }
        if (!this->skipExact("  }")) {
            return false;
        }
        if ('\n' == this->peek()) {
            break;
        }
        if (!this->skipExact(",\n")) {
            return false;
        }
    }
    return true;
}

bool FiddleParser::textOut(Definition* example, const char* stdOutStart,
        const char* stdOutEnd) {
    bool foundStdOut = false;
    for (auto& textOut : example->fChildren) {
        if (MarkType::kStdOut != textOut->fMarkType) {
            continue;
        }
        foundStdOut = true;
        bool foundVolatile = false;
        for (auto& stdOutChild : textOut->fChildren) {
                if (MarkType::kVolatile == stdOutChild->fMarkType) {
                    foundVolatile = true;
                    break;
                }
        }
        TextParser bmh(textOut);
        EscapeParser fiddle(stdOutStart, stdOutEnd);
        do {
            bmh.skipWhiteSpace();
            fiddle.skipWhiteSpace();
            const char* bmhEnd = bmh.trimmedLineEnd();
            const char* fiddleEnd = fiddle.trimmedLineEnd();
            ptrdiff_t bmhLen = bmhEnd - bmh.fChar;
            SkASSERT(bmhLen > 0);
            ptrdiff_t fiddleLen = fiddleEnd - fiddle.fChar;
            SkASSERT(fiddleLen > 0);
            if (bmhLen != fiddleLen) {
                if (!foundVolatile) {
                    bmh.reportError("mismatched stdout len\n");
                }
            } else  if (strncmp(bmh.fChar, fiddle.fChar, fiddleLen)) {
                if (!foundVolatile) {
                    bmh.reportError("mismatched stdout text\n");
                }
            }
            bmh.skipToLineStart();
            fiddle.skipToLineStart();
        } while (!bmh.eof() && !fiddle.eof());
        if (!foundStdOut) {
            bmh.reportError("bmh %s missing stdout\n");
        } else if (!bmh.eof() || !fiddle.eof()) {
            if (!foundVolatile) {
                bmh.reportError("%s mismatched stdout eof\n");
            }
        }
    }
    return true;
}
