/*
 * Copyright (c) 2001-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * 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;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "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 THE COPYRIGHT
 * OWNER 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.
 */

#include <ctype.h>
#include <fstream>
#include <iostream>
#include <list>
#include <string>
#include <vector>

#include "base/misc.hh"
#include "base/trace.hh"
#include "base/str.hh"

using namespace std;

namespace Trace {
const string DefaultName("global");
FlagVec flags(NumFlags, false);

//
// This variable holds the output stream for debug information.  Other
// than setting up/redirecting this stream, do *NOT* reference this
// directly; use DebugOut() (see below) to access this stream for
// output.
//
ostream *dprintf_stream = &cerr;

ObjectMatch ignore;

Log theLog;

Log::Log()
{
    size = 0;
    buffer = NULL;
}


void
Log::init(int _size)
{
    if (buffer != NULL) {
        fatal("Trace::Log::init called twice!");
    }

    size = _size;

    buffer = new Record *[size];

    for (int i = 0; i < size; ++i) {
        buffer[i] = NULL;
    }

    nextRecPtr = &buffer[0];
    wrapRecPtr = &buffer[size];
}


Log::~Log()
{
    for (int i = 0; i < size; ++i) {
        delete buffer[i];
    }

    delete [] buffer;
}


void
Log::append(Record *rec)
{
    // dump record to output stream if there's one open
    if (dprintf_stream != NULL) {
        rec->dump(*dprintf_stream);
    } else {
        rec->dump(cout);
    }

    // no buffering: justget rid of it now
    if (buffer == NULL) {
        delete rec;
        return;
    }

    Record *oldRec = *nextRecPtr;

    if (oldRec != NULL) {
        // log has wrapped: overwrite
        delete oldRec;
    }

    *nextRecPtr = rec;

    if (++nextRecPtr == wrapRecPtr) {
        nextRecPtr = &buffer[0];
    }
}


void
Log::dump(ostream &os)
{
    if (buffer == NULL) {
        return;
    }

    Record **bufPtr = nextRecPtr;

    if (*bufPtr == NULL) {
        // next record slot is empty: log must not be full yet.
        // start dumping from beginning of buffer
        bufPtr = buffer;
    }

    do {
        Record *rec = *bufPtr;

        rec->dump(os);

        if (++bufPtr == wrapRecPtr) {
            bufPtr = &buffer[0];
        }
    } while (bufPtr != nextRecPtr);
}

PrintfRecord::~PrintfRecord()
{
    delete &args;
}

void
PrintfRecord::dump(ostream &os)
{
    string fmt = "";

    if (!name.empty()) {
        fmt = "%s: " + fmt;
        args.prepend(name);
    }

    if (cycle != (Tick)-1) {
        fmt = "%7d: " + fmt;
        args.prepend(cycle);
    }

    fmt += format;

    args.dump(os, fmt);
    os.flush();
}

DataRecord::DataRecord(Tick _cycle, const string &_name,
                       const void *_data, int _len)
    : Record(_cycle), name(_name), len(_len)
{
    data = new uint8_t[len];
    memcpy(data, _data, len);
}

DataRecord::~DataRecord()
{
    delete [] data;
}

void
DataRecord::dump(ostream &os)
{
    int c, i, j;

    for (i = 0; i < len; i += 16) {
        ccprintf(os, "%d: %s: %08x  ", cycle, name, i);
        c = len - i;
        if (c > 16) c = 16;

        for (j = 0; j < c; j++) {
            ccprintf(os, "%02x ", data[i + j] & 0xff);
            if ((j & 0xf) == 7 && j > 0)
                ccprintf(os, " ");
        }

        for (; j < 16; j++)
            ccprintf(os, "   ");
        ccprintf(os, "  ");

        for (j = 0; j < c; j++) {
            int ch = data[i + j] & 0x7f;
            ccprintf(os,
                     "%c", (char)(isprint(ch) ? ch : ' '));
        }

        ccprintf(os, "\n");

        if (c < 16)
            break;
    }
}
} // namespace Trace

//
// Returns the current output stream for debug information.  As a
// wrapper around Trace::dprintf_stream, this handles cases where debug
// information is generated in the process of parsing .ini options,
// before we process the option that sets up the debug output stream
// itself.
//
std::ostream &
DebugOut()
{
    return *Trace::dprintf_stream;
}

/////////////////////////////////////////////
//
// C-linkage functions for invoking from gdb
//
/////////////////////////////////////////////

//
// Dump trace buffer to specified file (cout if NULL)
//
extern "C"
void
dumpTrace(const char *filename)
{
    if (filename != NULL) {
        ofstream out(filename);
        Trace::theLog.dump(out);
        out.close();
    }
    else {
        Trace::theLog.dump(cout);
    }
}


//
// Turn on/off trace output to cerr.  Typically used when trace output
// is only going to circular buffer, but you want to see what's being
// sent there as you step through some code in gdb.  This uses the
// same facility as the "trace to file" feature, and will print error
// messages rather than clobbering an existing ostream pointer.
//
extern "C"
void
echoTrace(bool on)
{
    if (on) {
        if (Trace::dprintf_stream != NULL) {
            cerr << "Already echoing trace to a file... go do a 'tail -f'"
                 << " on that file instead." << endl;
        } else {
            Trace::dprintf_stream = &cerr;
        }
    } else {
        if (Trace::dprintf_stream != &cerr) {
            cerr << "Not echoing trace to cerr." << endl;
        } else {
            Trace::dprintf_stream = NULL;
        }
    }
}

extern "C"
void
printTraceFlags()
{
    using namespace Trace;
    for (int i = 0; i < numFlagStrings; ++i)
        if (flags[i])
            cprintf("%s\n", flagStrings[i]);
}

void
tweakTraceFlag(const char *string, bool value)
{
    using namespace Trace;
    std::string str(string);

    for (int i = 0; i < numFlagStrings; ++i) {
        if (str != flagStrings[i])
            continue;

        int idx = i;

        if (idx < NumFlags) {
            flags[idx] = value;
        } else {
            idx -= NumFlags;
            if (idx >= NumCompoundFlags) {
                ccprintf(cerr, "Invalid compound flag");
                return;
            }

            const Flags *flagVec = compoundFlags[idx];

            for (int j = 0; flagVec[j] != -1; ++j) {
                if (flagVec[j] >= NumFlags) {
                    ccprintf(cerr, "Invalid compound flag");
                    return;
                }
                flags[flagVec[j]] = value;
            }
        }

        cprintf("flag %s was %s\n", string, value ? "set" : "cleared");
        return;
    }

    cprintf("could not find flag %s\n", string);
}

extern "C"
void
setTraceFlag(const char *string)
{
    tweakTraceFlag(string, true);
}

extern "C"
void
clearTraceFlag(const char *string)
{
    tweakTraceFlag(string, false);
}
