/*
 * Copyright (c) 2015 ARM Limited
 * 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.
 *
 * Authors: Nathan Binkert
 *          Chris Emmons
 *          Andreas Sandberg
 *          Sascha Bischoff
 */

#ifndef __BASE_OUTPUT_HH__
#define __BASE_OUTPUT_HH__

#include <ios>
#include <map>
#include <string>

#include "base/compiler.hh"

class OutputDirectory;

class OutputStream
{
  public:
    virtual ~OutputStream();

    /** Get the output underlying output stream */
    std::ostream *stream() const { return _stream; };

    /**
     * Can the file be recreated if the output directory is moved?
     *
     * @return true if the file will be created in the new location,
     * false otherwise.
     */
    virtual bool recreateable() const { return false; }

    /** Get the file name in the output directory */
    const std::string &name() const { return _name; }

  protected:
    friend class OutputDirectory;

    /** Wrap an existing stream */
    OutputStream(const std::string &name,
                 std::ostream *stream);

    /* Prevent copying */
    OutputStream(const OutputStream &f);

    /** Re-create the in a new location if recreateable. */
    virtual void relocate(const OutputDirectory &dir);

    /** Name in output directory */
    const std::string _name;

    /** Underlying output stream */
    std::ostream *const _stream;
};

template<class StreamType>
class OutputFile
    : public OutputStream
{
  public:
    typedef StreamType stream_type_t;

    virtual ~OutputFile();

    /**
     * Can the file be recreated if the output directory is moved?
     *
     * @return true if the file will be created in the new location,
     * false otherwise.
     */
    bool recreateable() const override { return _recreateable; }

  protected:
    friend class OutputDirectory;

    OutputFile(const OutputDirectory &dir,
               const std::string &name,
               std::ios_base::openmode mode,
               bool recreateable);

    /* Prevent copying */
    OutputFile(const OutputFile<StreamType> &f);

    /** Re-create the file in a new location if it is relocatable. */
    void relocate(const OutputDirectory &dir) override;

    /** File mode when opened */
    const std::ios_base::openmode _mode;

    /** Can the file be recreated in a new location? */
    const bool _recreateable;

    /** Pointer to the file stream */
    stream_type_t *const _fstream;
};

/** Interface for creating files in a gem5 output directory. */
class OutputDirectory
{
  private:
    /** File names and associated stream handles */
    typedef std::map<std::string, OutputStream *> file_map_t;

    /** Output subdirectories */
    typedef std::map<std::string, OutputDirectory *> dir_map_t;

    /** Open file streams within this directory */
    file_map_t files;

    /** Output sub-directories */
    dir_map_t dirs;

    /** Name of this directory */
    std::string dir;

    /** System-specific path separator character */
    static const char PATH_SEPARATOR = '/';

    static OutputStream stdout;
    static OutputStream stderr;

  protected:
    /**
     * Determines whether given file name corresponds to standard output
     * streams.
     *
     * @param name name of file to check
     * @return output stream for standard output or error stream if name
     *         corresponds to one or the other; NULL otherwise
     */
    static OutputStream *checkForStdio(const std::string &name);

  public:
    /** Constructor. */
    OutputDirectory();

    /** Constructor. */
    OutputDirectory(const std::string &name);

    /** Destructor. */
    ~OutputDirectory();

    /**
     * Returns relative file names prepended with name of this directory.
     * Returns absolute file names unaltered.
     *
     * @param name file name to prepend with directory name
     * @return file name prepended with base directory name or unaltered
     *          absolute file name
     */
    std::string resolve(const std::string &name) const;

    /**
     * Sets name of this directory.
     * @param dir name of this directory
     */
    void setDirectory(const std::string &dir);

    /**
     * Gets name of this directory.
     * @return name of this directory
     */
    const std::string &directory() const;

    /**
     * Creates a file in this directory (optionally compressed).
     *
     * Will open a file as a compressed stream if filename ends in .gz, unless
     * explicitly disabled.
     *
     * Relative output paths will result in the creation of a
     * recreateable (see OutputFile) output file in the current output
     * directory. Files created with an absolute path will not be
     * recreateable.
     *
     * @param name name of file to create (without this directory's name
     *          leading it)
     * @param binary true to create a binary file; false otherwise
     * @param no_gz true to disable opening the file as a gzip compressed output
     *     stream; false otherwise
     * @return OutputStream instance representing the created file
     */
    OutputStream *create(const std::string &name,
                         bool binary = false,
                         bool no_gz = false);

    /**
     * Open a file in this directory (optionally compressed).
     *
     * Will open a file as a compressed stream if filename ends in .gz, unless
     * explicitly disabled.
     *
     * @param filename file to open
     * @param mode attributes to open file with
     * @param recreateable Set to true if the file can be recreated in a new
     *     location.
     * @param no_gz true to disable opening the file as a gzip compressed output
     *     stream; false otherwise
     * @return OutputStream instance representing the opened file
     */
    OutputStream *open(const std::string &name,
                       std::ios_base::openmode mode,
                       bool recreateable = true,
                       bool no_gz = false);

    /**
     * Closes an output file and free the corresponding OutputFile.
     *
     * The output file must have been opened by the same
     * OutputDirectory instance as the one closing it, or sim will
     * fail.
     *
     * @param file OutputStream instance in this OutputDirectory.
     */
    void close(OutputStream *file);

    /**
     * Finds stream associated with an open file or stdout/stderr.
     *
     * @param name of file
     * @return stream to specified file or NULL if file does not exist
     */
    OutputStream *find(const std::string &name) const;

    OutputStream *findOrCreate(const std::string &name, bool binary = false);

    /**
     * Determines whether a file name corresponds to a file in this directory.
     * @param name name of file to evaluate
     * @return true iff file has been opened in this directory or exists on the
     *          file system within this directory
     */
    bool isFile(const std::string &name) const;

    /**
     * Test if a path is absolute.
     */
    static inline bool isAbsolute(const std::string &name) {
        return name[0] == PATH_SEPARATOR;
    }

    /**
     * Creates a subdirectory within this directory.
     * @param name name of subdirectory
     * @return the new subdirectory's name suffixed with a path separator
     */
    OutputDirectory *createSubdirectory(const std::string &name);

    /**
     * Removes a specified file or subdirectory.
     *
     * Will cause sim to fail for most errors.  However, it will only warn the
     * user if a directory could not be removed.  This is in place to
     * accommodate slow file systems where file deletions within a subdirectory
     * may not be recognized quickly enough thereby causing the subsequent call
     * to remove the directory to fail (seemingly unempty directory).
     *
     * @param name name of file or subdirectory to remove; name should not
     *              be prepended with the name of this directory object
     * @param recursive set to true to attempt to recursively delete a
     *                  subdirectory and its contents
     */
    void remove(const std::string &name, bool recursive=false);
};

extern OutputDirectory simout;

#endif // __BASE_OUTPUT_HH__
