/*
 * Copyright (C) 2017 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include "CPU.h"

#include <wtf/PrintStream.h>
#include <wtf/StringPrintStream.h>
#include <wtf/Vector.h>

namespace JSC {

namespace Probe {
class Context;
} // namespace Probe

namespace Printer {

struct Context;

union Data {
    Data()
    {
        const intptr_t uninitialized = 0xdeadb0d0;
        memcpy(&buffer, &uninitialized, sizeof(uninitialized));
    }
    Data(uintptr_t value)
        : Data(&value, sizeof(value))
    { }
    Data(const void* pointer)
        : Data(&pointer, sizeof(pointer))
    { }
    Data(void* src, size_t size)
    {
        RELEASE_ASSERT(size <= sizeof(buffer));
        memcpy(&buffer, src, size);
    }

    template<typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type>
    T as() const
    {
        return static_cast<T>(value);
    }

    template<typename T, typename = typename std::enable_if<std::is_pointer<T>::value>::type>
    const T as(int = 0) const
    {
        return reinterpret_cast<const T>(pointer);
    }

    template<typename T, typename = typename std::enable_if<!std::is_integral<T>::value && !std::is_pointer<T>::value>::type>
    const T& as() const
    {
        static_assert(sizeof(T) <= sizeof(buffer), "size is not sane");
        return *reinterpret_cast<const T*>(&buffer);
    }

    uintptr_t value;
    const void* pointer;
#if USE(JSVALUE64)
    UCPURegister buffer[4];
#elif USE(JSVALUE32_64)
    UCPURegister buffer[6];
#endif
};

struct Context {
    Context(Probe::Context& probeContext, Data& data)
        : probeContext(probeContext)
        , data(data)
    { }

    Probe::Context& probeContext;
    Data& data;
};

typedef void (*Callback)(PrintStream&, Context&);

struct PrintRecord {
    PrintRecord(Data data, Callback printer)
        : data(data)
        , printer(printer)
    { }

    PrintRecord(Callback printer)
        : printer(printer)
    { }

    template<template<class> class Printer, typename T>
    PrintRecord(const Printer<T>& other)
    {
        static_assert(std::is_base_of<PrintRecord, Printer<T>>::value, "Printer should extend PrintRecord");
        static_assert(sizeof(PrintRecord) == sizeof(Printer<T>), "Printer should be the same size as PrintRecord");
        data = other.data;
        printer = other.printer;
    }

    Data data;
    Callback printer;

protected:
    PrintRecord() { }
};

template<typename T> struct Printer;

typedef Vector<PrintRecord> PrintRecordList;

inline void appendPrinter(PrintRecordList&) { }

template<typename First, typename... Arguments>
inline void appendPrinter(PrintRecordList& printRecordList, First first, Arguments&&... others)
{
    printRecordList.append(Printer<First>(first));
    appendPrinter(printRecordList, std::forward<Arguments>(others)...);
}

template<typename... Arguments>
inline PrintRecordList* makePrintRecordList(Arguments&&... arguments)
{
    // FIXME: the current implementation intentionally leaks the PrintRecordList.
    // We may want to fix this in the future if we want to use the print mechanism
    // in tests that may compile a lot of prints.
    // https://bugs.webkit.org/show_bug.cgi?id=171123
    auto printRecordList = new PrintRecordList();
    appendPrinter(*printRecordList, std::forward<Arguments>(arguments)...);
    return printRecordList;
}

// Some utility functions for specializing printers.

void printConstCharString(PrintStream&, Context&);
void printIntptr(PrintStream&, Context&);
void printUintptr(PrintStream&, Context&);
void printPointer(PrintStream&, Context&);

void setPrinter(PrintRecord&, CString&&);

// Specialized printers.

template<>
struct Printer<const char*> : public PrintRecord {
    Printer(const char* str)
        : PrintRecord(str, printConstCharString)
    { }
};

template<>
struct Printer<char*> : public Printer<const char*> {
    Printer(char* str)
        : Printer<const char*>(str)
    { }
};

template<>
struct Printer<RawPointer> : public PrintRecord {
    Printer(RawPointer rawPointer)
        : PrintRecord(rawPointer.value(), printPointer)
    { }
};

template<typename T, typename = typename std::enable_if_t<std::is_integral<T>::value && std::numeric_limits<T>::is_signed>>
void setPrinter(PrintRecord& record, T value, intptr_t = 0)
{
    record.data.value = static_cast<uintptr_t>(value);
    record.printer = printIntptr;
}

template<typename T, typename = typename std::enable_if_t<std::is_integral<T>::value && !std::numeric_limits<T>::is_signed>>
void setPrinter(PrintRecord& record, T value, uintptr_t = 0)
{
    record.data.value = static_cast<uintptr_t>(value);
    record.printer = printUintptr;
}

template<typename T>
struct Printer : public PrintRecord {
    Printer(T value)
    {
        setPrinter(*this, value);
    }
};

} // namespace Printer

} // namespace JSC
