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

#ifndef SkJSONWriter_DEFINED
#define SkJSONWriter_DEFINED

#include "include/core/SkStream.h"
#include "include/core/SkTypes.h"
#include "include/private/SkNoncopyable.h"
#include "include/private/SkTArray.h"

#include <string.h>

/**
 *  Lightweight class for writing properly structured JSON data. No random-access, everything must
 *  be generated in-order. The resulting JSON is written directly to the SkWStream supplied at
 *  construction time. Output is buffered, so writing to disk (via an SkFILEWStream) is ideal.
 *
 *  There is a basic state machine to ensure that JSON is structured correctly, and to allow for
 *  (optional) pretty formatting.
 *
 *  This class adheres to the RFC-4627 usage of JSON (not ECMA-404). In other words, all JSON
 *  created with this class must have a top-level object or array. Free-floating values of other
 *  types are not considered valid.
 *
 *  Note that all error checking is in the form of asserts - invalid usage in a non-debug build
 *  will simply produce invalid JSON.
 */
class SkJSONWriter : SkNoncopyable {
public:
    enum class Mode {
        /**
         *  Output the minimal amount of text. No additional whitespace (including newlines) is
         *  generated. The resulting JSON is suitable for fast parsing and machine consumption.
         */
        kFast,

        /**
         *  Output human-readable JSON, with indented  objects and arrays, and one value per line.
         *  Slightly slower than kFast, and produces data that is somewhat larger.
         */
        kPretty
    };

    /**
     *  Construct a JSON writer that will serialize all the generated JSON to 'stream'.
     */
    SkJSONWriter(SkWStream* stream, Mode mode = Mode::kFast)
            : fBlock(new char[kBlockSize])
            , fWrite(fBlock)
            , fBlockEnd(fBlock + kBlockSize)
            , fStream(stream)
            , fMode(mode)
            , fState(State::kStart) {
        fScopeStack.push_back(Scope::kNone);
        fNewlineStack.push_back(true);
    }

    ~SkJSONWriter() {
        this->flush();
        delete[] fBlock;
        SkASSERT(fScopeStack.count() == 1);
        SkASSERT(fNewlineStack.count() == 1);
    }

    /**
     *  Force all buffered output to be flushed to the underlying stream.
     */
    void flush() {
        if (fWrite != fBlock) {
            fStream->write(fBlock, fWrite - fBlock);
            fWrite = fBlock;
        }
    }

    /**
     *  Append the name (key) portion of an object member. Must be called between beginObject() and
     *  endObject(). If you have both the name and value of an object member, you can simply call
     *  the two argument versions of the other append functions.
     */
    void appendName(const char* name) {
        if (!name) {
            return;
        }
        SkASSERT(Scope::kObject == this->scope());
        SkASSERT(State::kObjectBegin == fState || State::kObjectValue == fState);
        if (State::kObjectValue == fState) {
            this->write(",", 1);
        }
        this->separator(this->multiline());
        this->write("\"", 1);
        this->write(name, strlen(name));
        this->write("\":", 2);
        fState = State::kObjectName;
    }

    /**
     *  Adds a new object. A name must be supplied when called between beginObject() and
     *  endObject(). Calls to beginObject() must be balanced by corresponding calls to endObject().
     *  By default, objects are written out with one named value per line (when in kPretty mode).
     *  This can be overridden for a particular object by passing false for multiline, this will
     *  keep the entire object on a single line. This can help with readability in some situations.
     *  In kFast mode, this parameter is ignored.
     */
    void beginObject(const char* name = nullptr, bool multiline = true) {
        this->appendName(name);
        this->beginValue(true);
        this->write("{", 1);
        fScopeStack.push_back(Scope::kObject);
        fNewlineStack.push_back(multiline);
        fState = State::kObjectBegin;
    }

    /**
     *  Ends an object that was previously started with beginObject().
     */
    void endObject() {
        SkASSERT(Scope::kObject == this->scope());
        SkASSERT(State::kObjectBegin == fState || State::kObjectValue == fState);
        bool emptyObject = State::kObjectBegin == fState;
        bool wasMultiline = this->multiline();
        this->popScope();
        if (!emptyObject) {
            this->separator(wasMultiline);
        }
        this->write("}", 1);
    }

    /**
     *  Adds a new array. A name must be supplied when called between beginObject() and
     *  endObject(). Calls to beginArray() must be balanced by corresponding calls to endArray().
     *  By default, arrays are written out with one value per line (when in kPretty mode).
     *  This can be overridden for a particular array by passing false for multiline, this will
     *  keep the entire array on a single line. This can help with readability in some situations.
     *  In kFast mode, this parameter is ignored.
     */
    void beginArray(const char* name = nullptr, bool multiline = true) {
        this->appendName(name);
        this->beginValue(true);
        this->write("[", 1);
        fScopeStack.push_back(Scope::kArray);
        fNewlineStack.push_back(multiline);
        fState = State::kArrayBegin;
    }

    /**
     *  Ends an array that was previous started with beginArray().
     */
    void endArray() {
        SkASSERT(Scope::kArray == this->scope());
        SkASSERT(State::kArrayBegin == fState || State::kArrayValue == fState);
        bool emptyArray = State::kArrayBegin == fState;
        bool wasMultiline = this->multiline();
        this->popScope();
        if (!emptyArray) {
            this->separator(wasMultiline);
        }
        this->write("]", 1);
    }

    /**
     *  Functions for adding values of various types. The single argument versions add un-named
     *  values, so must be called either
     *  - Between beginArray() and endArray()                                -or-
     *  - Between beginObject() and endObject(), after calling appendName()
     */
    void appendString(const char* value) {
        this->beginValue();
        this->write("\"", 1);
        if (value) {
            while (*value) {
                switch (*value) {
                    case '"': this->write("\\\"", 2); break;
                    case '\\': this->write("\\\\", 2); break;
                    case '\b': this->write("\\b", 2); break;
                    case '\f': this->write("\\f", 2); break;
                    case '\n': this->write("\\n", 2); break;
                    case '\r': this->write("\\r", 2); break;
                    case '\t': this->write("\\t", 2); break;
                    default: this->write(value, 1); break;
                }
                value++;
            }
        }
        this->write("\"", 1);
    }

    void appendPointer(const void* value) { this->beginValue(); this->appendf("\"%p\"", value); }
    void appendBool(bool value) {
        this->beginValue();
        if (value) {
            this->write("true", 4);
        } else {
            this->write("false", 5);
        }
    }
    void appendS32(int32_t value) { this->beginValue(); this->appendf("%d", value); }
    void appendS64(int64_t value);
    void appendU32(uint32_t value) { this->beginValue(); this->appendf("%u", value); }
    void appendU64(uint64_t value);
    void appendFloat(float value) { this->beginValue(); this->appendf("%g", value); }
    void appendDouble(double value) { this->beginValue(); this->appendf("%g", value); }
    void appendFloatDigits(float value, int digits) {
        this->beginValue();
        this->appendf("%.*g", digits, value);
    }
    void appendDoubleDigits(double value, int digits) {
        this->beginValue();
        this->appendf("%.*g", digits, value);
    }
    void appendHexU32(uint32_t value) { this->beginValue(); this->appendf("\"0x%x\"", value); }
    void appendHexU64(uint64_t value);

#define DEFINE_NAMED_APPEND(function, type) \
    void function(const char* name, type value) { this->appendName(name); this->function(value); }

    /**
     *  Functions for adding named values of various types. These add a name field, so must be
     *  called between beginObject() and endObject().
     */
    DEFINE_NAMED_APPEND(appendString, const char *)
    DEFINE_NAMED_APPEND(appendPointer, const void *)
    DEFINE_NAMED_APPEND(appendBool, bool)
    DEFINE_NAMED_APPEND(appendS32, int32_t)
    DEFINE_NAMED_APPEND(appendS64, int64_t)
    DEFINE_NAMED_APPEND(appendU32, uint32_t)
    DEFINE_NAMED_APPEND(appendU64, uint64_t)
    DEFINE_NAMED_APPEND(appendFloat, float)
    DEFINE_NAMED_APPEND(appendDouble, double)
    DEFINE_NAMED_APPEND(appendHexU32, uint32_t)
    DEFINE_NAMED_APPEND(appendHexU64, uint64_t)

#undef DEFINE_NAMED_APPEND

    void appendFloatDigits(const char* name, float value, int digits) {
        this->appendName(name);
        this->appendFloatDigits(value, digits);
    }
    void appendDoubleDigits(const char* name, double value, int digits) {
        this->appendName(name);
        this->appendDoubleDigits(value, digits);
    }

private:
    enum {
        // Using a 32k scratch block gives big performance wins, but we diminishing returns going
        // any larger. Even with a 1MB block, time to write a large (~300 MB) JSON file only drops
        // another ~10%.
        kBlockSize = 32 * 1024,
    };

    enum class Scope {
        kNone,
        kObject,
        kArray
    };

    enum class State {
        kStart,
        kEnd,
        kObjectBegin,
        kObjectName,
        kObjectValue,
        kArrayBegin,
        kArrayValue,
    };

    void appendf(const char* fmt, ...) SK_PRINTF_LIKE(2, 3);

    void beginValue(bool structure = false) {
        SkASSERT(State::kObjectName == fState ||
                 State::kArrayBegin == fState ||
                 State::kArrayValue == fState ||
                 (structure && State::kStart == fState));
        if (State::kArrayValue == fState) {
            this->write(",", 1);
        }
        if (Scope::kArray == this->scope()) {
            this->separator(this->multiline());
        } else if (Scope::kObject == this->scope() && Mode::kPretty == fMode) {
            this->write(" ", 1);
        }
        // We haven't added the value yet, but all (non-structure) callers emit something
        // immediately, so transition state, to simplify the calling code.
        if (!structure) {
            fState = Scope::kArray == this->scope() ? State::kArrayValue : State::kObjectValue;
        }
    }

    void separator(bool multiline) {
        if (Mode::kPretty == fMode) {
            if (multiline) {
                this->write("\n", 1);
                for (int i = 0; i < fScopeStack.count() - 1; ++i) {
                    this->write("   ", 3);
                }
            } else {
                this->write(" ", 1);
            }
        }
    }

    void write(const char* buf, size_t length) {
        if (static_cast<size_t>(fBlockEnd - fWrite) < length) {
            // Don't worry about splitting writes that overflow our block.
            this->flush();
        }
        if (length > kBlockSize) {
            // Send particularly large writes straight through to the stream (unbuffered).
            fStream->write(buf, length);
        } else {
            memcpy(fWrite, buf, length);
            fWrite += length;
        }
    }

    Scope scope() const {
        SkASSERT(!fScopeStack.empty());
        return fScopeStack.back();
    }

    bool multiline() const {
        SkASSERT(!fNewlineStack.empty());
        return fNewlineStack.back();
    }

    void popScope() {
        fScopeStack.pop_back();
        fNewlineStack.pop_back();
        switch (this->scope()) {
            case Scope::kNone:
                fState = State::kEnd;
                break;
            case Scope::kObject:
                fState = State::kObjectValue;
                break;
            case Scope::kArray:
                fState = State::kArrayValue;
                break;
            default:
                SkDEBUGFAIL("Invalid scope");
                break;
        }
    }

    char* fBlock;
    char* fWrite;
    char* fBlockEnd;

    SkWStream* fStream;
    Mode fMode;
    State fState;
    SkSTArray<16, Scope, true> fScopeStack;
    SkSTArray<16, bool, true> fNewlineStack;
};

#endif
