/*
 * Copyright (c) 2015 ARM Limited
 * Copyright (c) 2020 Barkhausen Institut
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2013 Andreas Sandberg
 * Copyright (c) 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 "base/output.hh"

#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <zfstream.h>

#include <cassert>
#include <cerrno>
#include <climits>
#include <cstdlib>
#include <fstream>

#include "base/logging.hh"

namespace gem5
{

OutputDirectory simout;


OutputStream::OutputStream(const std::string &name, std::ostream *stream)
    : _name(name), _stream(stream)
{
}

OutputStream::~OutputStream()
{
}

void
OutputStream::relocate(const OutputDirectory &dir)
{
}

template<class StreamType>
OutputFile<StreamType>::OutputFile(const OutputDirectory &dir,
                                   const std::string &name,
                                   std::ios_base::openmode mode,
                                   bool recreateable)
  : OutputStream(name, new stream_type_t()),
    _mode(mode), _recreateable(recreateable),
    _fstream(static_cast<stream_type_t *>(_stream))
{
    std::string resolved_path = dir.resolve(_name);

    _fstream->open(resolved_path.c_str(), _mode);

    panic_if(!_fstream->is_open(), "Failed to open \"%s\"\n", resolved_path);
}

template<class StreamType>
OutputFile<StreamType>::~OutputFile()
{
    if (_fstream->is_open())
        _fstream->close();
}

template<class StreamType>
void
OutputFile<StreamType>::relocate(const OutputDirectory &dir)
{
    if (_recreateable) {
        _fstream->close();
        _fstream->open(dir.resolve(_name).c_str(), _mode);
    }
}

OutputStream OutputDirectory::stdout("stdout", &std::cout);
OutputStream OutputDirectory::stderr("stderr", &std::cerr);

/**
 * @file This file manages creating / deleting output files for the simulator.
 */
OutputDirectory::OutputDirectory()
{}

OutputDirectory::OutputDirectory(const std::string &name)
{
    setDirectory(name);
}

OutputDirectory::~OutputDirectory()
{
    for (auto& f: files) {
        if (f.second)
            delete f.second;
    }
}

OutputStream *
OutputDirectory::checkForStdio(const std::string &name)
{
    if (name == "cerr" || name == "stderr")
        return &stderr;

    if (name == "cout" || name == "stdout")
        return &stdout;

    return NULL;
}

void
OutputDirectory::close(OutputStream *file)
{
    if (file == &stdout || file == &stderr) {
        file->stream()->flush();
        return;
    }

    auto i = files.find(file->name());
    if (i == files.end())
        fatal("Attempted to close an unregistred file stream");

    files.erase(i);

    delete file;
}

void
OutputDirectory::setDirectory(const std::string &d)
{
    const std::string old_dir(dir);

    dir = d;

    // guarantee that directory ends with a path separator
    if (dir[dir.size() - 1] != PATH_SEPARATOR)
        dir += PATH_SEPARATOR;

    // Try to create the directory. If it already exists, that's ok;
    // otherwise, fail if we couldn't create it.
    if ((mkdir(dir.c_str(), 0755) != 0) && (errno != EEXIST))
        fatal("Failed to create new output subdirectory '%s'\n", dir);

    // Check if we need to recreate anything
    if (!old_dir.empty()) {
        // Recreate output files
        for (file_map_t::iterator i = files.begin(); i != files.end(); ++i) {
            i->second->relocate(*this);
        }

        // Relocate sub-directories
        for (dir_map_t::iterator i = dirs.begin(); i != dirs.end(); ++i) {
            i->second->setDirectory(dir + PATH_SEPARATOR + i->first);
        }
    }

}

const std::string &
OutputDirectory::directory() const
{
    if (dir.empty())
        panic("Output directory not set!");

    return dir;
}

std::string
OutputDirectory::resolve(const std::string &name) const
{
    return !isAbsolute(name) ? dir + name : name;
}

OutputStream *
OutputDirectory::create(const std::string &name, bool binary, bool no_gz)
{
    OutputStream *file = checkForStdio(name);
    if (file)
        return file;

    const std::ios_base::openmode mode(
        std::ios::trunc | (binary ? std::ios::binary : (std::ios::openmode)0));
    const bool recreateable(!isAbsolute(name));

    return open(name, mode, recreateable, no_gz);
}

OutputStream *
OutputDirectory::open(const std::string &name,
                      std::ios_base::openmode mode,
                      bool recreateable,
                      bool no_gz)
{
    OutputStream *os;

    if (!no_gz && name.find(".gz", name.length() - 3) < name.length()) {
        // Although we are creating an output stream, we still need to pass the
        // correct mode for gzofstream as this used directly to set the file
        // mode.
        mode |= std::ios::out;
        os = new OutputFile<gzofstream>(*this, name, mode, recreateable);
    } else {
        os = new OutputFile<std::ofstream>(*this, name, mode, recreateable);
    }

    files[name] = os;

    return os;
}

OutputStream *
OutputDirectory::find(const std::string &name) const
{
    OutputStream *file = checkForStdio(name);
    if (file)
        return file;

    auto i = files.find(name);
    if (i != files.end())
        return (*i).second;

    return NULL;
}


OutputStream *
OutputDirectory::findOrCreate(const std::string &name, bool binary)
{
    OutputStream *os(find(name));
    if (os)
        return os;
    else
        return create(name, binary);
}

bool
OutputDirectory::isFile(const std::string &name) const
{
    // definitely a file if in our data structure
    if (find(name) != NULL) return true;

    struct stat st_buf;
    int st = stat(name.c_str(), &st_buf);
    return (st == 0) && S_ISREG(st_buf.st_mode);
}

OutputDirectory *
OutputDirectory::createSubdirectory(const std::string &name)
{
    const std::string new_dir = resolve(name);
    if (new_dir.find(directory()) == std::string::npos)
        fatal("Attempting to create subdirectory not in m5 output dir\n");

    OutputDirectory *dir(new OutputDirectory(new_dir));
    dirs[name] = dir;

    return dir;
}

void
OutputDirectory::remove(const std::string &name, bool recursive)
{
    const std::string fname = resolve(name);

    if (fname.find(directory()) == std::string::npos)
        fatal("Attempting to remove file/dir not in output dir\n");

    if (isFile(fname)) {
        // close and release file if we have it open
        auto i = files.find(fname);
        if (i != files.end()) {
            delete i->second;
            files.erase(i);
        }

        if (::remove(fname.c_str()) != 0)
            fatal("Could not erase file '%s'\n", fname);
    } else {
        // assume 'name' is a directory
        if (recursive) {
            DIR *subdir = opendir(fname.c_str());

            // silently ignore removal request for non-existent directory
            if ((!subdir) && (errno == ENOENT))
                return;

            // fail on other errors
            if (!subdir) {
                perror("opendir");
                fatal("Error opening directory for recursive removal '%s'\n",
                      fname);
            }

            struct dirent *de = readdir(subdir);
            while (de != NULL) {
                // ignore files starting with a '.'; user must delete those
                //   manually if they really want to
                if (de->d_name[0] != '.')
                    remove(name + PATH_SEPARATOR + de->d_name, recursive);

                de = readdir(subdir);
            }

            closedir(subdir);
        }

        // try to force recognition that we deleted the files in the directory
        sync();

        if (::remove(fname.c_str()) != 0) {
            perror("Warning!  'remove' failed.  Could not erase directory.");
        }
    }
}

} // namespace gem5
