/*
 * Copyright (c) 2016-2019 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.
 *
 * 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: Andreas Sandberg
 */

#include "base/stats/hdf5.hh"

#include "base/logging.hh"
#include "base/stats/info.hh"

/**
 * Check if all strings in a container are empty.
 */
template<typename T>
bool emptyStrings(const T &labels)
{
    for (const auto &s : labels) {
        if (!s.empty())
            return false;
    }
    return true;
}


namespace Stats {

Hdf5::Hdf5(const std::string &file, unsigned chunking,
           bool desc, bool formulas)
    : fname(file), timeChunk(chunking),
      enableDescriptions(desc), enableFormula(formulas),
      dumpCount(0)
{
    // Tell the library not to print exceptions by default. There are
    // cases where we rely on exceptions to determine if we need to
    // create a node or if we can just open it.
    H5::Exception::dontPrint();
}

Hdf5::~Hdf5()
{
}


void
Hdf5::begin()
{
    h5File = H5::H5File(fname,
                        // Truncate the file if this is the first dump
                        dumpCount > 0 ? H5F_ACC_RDWR : H5F_ACC_TRUNC);
    path.push(h5File.openGroup("/"));
}

void
Hdf5::end()
{
    assert(valid());

    dumpCount++;
}

bool
Hdf5::valid() const
{
    return true;
}


void
Hdf5::beginGroup(const char *name)
{
    auto base = path.top();

    // Try to open an existing stat group corresponding to the
    // name. Create it if it doesn't exist.
    H5::Group group;
    try {
        group = base.openGroup(name);
    } catch (const H5::FileIException& e) {
        group = base.createGroup(name);
    } catch (const H5::GroupIException& e) {
        group = base.createGroup(name);
    }

    path.push(group);
}

void
Hdf5::endGroup()
{
    assert(!path.empty());
    path.pop();
}

void
Hdf5::visit(const ScalarInfo &info)
{
    // Since this stat is a scalar, we need 1-dimensional value in the
    // stat file. The Hdf5::appendStat helper will populate the size
    // of the first dimension (time).
    hsize_t fdims[1] = { 0, };
    double data[1] = { info.result(), };

    appendStat(info, 1, fdims, data);
}

void
Hdf5::visit(const VectorInfo &info)
{
    appendVectorInfo(info);
}

void
Hdf5::visit(const DistInfo &info)
{
    warn_once("HDF5 stat files don't support distributions.\n");
}

void
Hdf5::visit(const VectorDistInfo &info)
{
    warn_once("HDF5 stat files don't support vector distributions.\n");
}

void
Hdf5::visit(const Vector2dInfo &info)
{
    // Request a 3-dimensional stat, the first dimension will be
    // populated by the Hdf5::appendStat() helper. The remaining two
    // dimensions correspond to the stat instance.
    hsize_t fdims[3] = { 0, info.x, info.y };
    H5::DataSet data_set = appendStat(info, 3, fdims, info.cvec.data());

    if (dumpCount == 0) {
        if (!info.subnames.empty() && !emptyStrings(info.subnames))
            addMetaData(data_set, "subnames", info.subnames);

        if (!info.y_subnames.empty() && !emptyStrings(info.y_subnames))
            addMetaData(data_set, "y_subnames", info.y_subnames);

        if (!info.subdescs.empty() && !emptyStrings(info.subdescs))
            addMetaData(data_set, "subdescs", info.subdescs);
    }
}

void
Hdf5::visit(const FormulaInfo &info)
{
    if (!enableFormula)
        return;

    H5::DataSet data_set = appendVectorInfo(info);

    if (dumpCount == 0)
        addMetaData(data_set, "equation", info.str());
}

void
Hdf5::visit(const SparseHistInfo &info)
{
    warn_once("HDF5 stat files don't support sparse histograms.\n");
}

H5::DataSet
Hdf5::appendVectorInfo(const VectorInfo &info)
{
    const VResult &vr(info.result());
    // Request a 2-dimensional stat, the first dimension will be
    // populated by the Hdf5::appendStat() helper. The remaining
    // dimension correspond to the stat instance.
    hsize_t fdims[2] = { 0, vr.size() };
    H5::DataSet data_set = appendStat(info, 2, fdims, vr.data());

    if (dumpCount == 0) {
        if (!info.subnames.empty() && !emptyStrings(info.subnames))
            addMetaData(data_set, "subnames", info.subnames);

        if (!info.subdescs.empty() && !emptyStrings(info.subdescs))
            addMetaData(data_set, "subdescs", info.subdescs);
    }

    return data_set;
}

H5::DataSet
Hdf5::appendStat(const Info &info, int rank, hsize_t *dims, const double *data)
{
    H5::Group group = path.top();
    H5::DataSet data_set;
    H5::DataSpace fspace;

    dims[0] = dumpCount + 1;

    if (dumpCount > 0) {
        // Get the existing stat if we have already dumped this stat
        // before.
        data_set = group.openDataSet(info.name);
        data_set.extend(dims);
        fspace = data_set.getSpace();
    } else {
        // We don't have the stat already, create it.

        H5::DSetCreatPropList props;

        // Setup max dimensions based on the requested file dimensions
        std::vector<hsize_t> max_dims(rank);
        std::copy(dims, dims + rank, max_dims.begin());
        max_dims[0] = H5S_UNLIMITED;

        // Setup chunking
        std::vector<hsize_t> chunk_dims(rank);
        std::copy(dims, dims + rank, chunk_dims.begin());
        chunk_dims[0] = timeChunk;
        props.setChunk(rank, chunk_dims.data());

        // Enable compression
        props.setDeflate(1);

        fspace = H5::DataSpace(rank, dims, max_dims.data());
        data_set = group.createDataSet(info.name, H5::PredType::NATIVE_DOUBLE,
                                       fspace, props);

        if (enableDescriptions && !info.desc.empty()) {
            addMetaData(data_set, "description", info.desc);
        }
    }

    // The first dimension is time which isn't included in data.
    dims[0] = 1;
    H5::DataSpace mspace(rank, dims);
    std::vector<hsize_t> foffset(rank, 0);
    foffset[0] = dumpCount;

    fspace.selectHyperslab(H5S_SELECT_SET, dims, foffset.data());
    data_set.write(data, H5::PredType::NATIVE_DOUBLE, mspace, fspace);

    return data_set;
}

void
Hdf5::addMetaData(H5::DataSet &loc, const char *name,
                  const std::vector<const char *> &values)
{
    H5::StrType type(H5::PredType::C_S1, H5T_VARIABLE);
    hsize_t dims[1] = { values.size(), };
    H5::DataSpace space(1, dims);
    H5::Attribute attribute = loc.createAttribute(name, type, space);
    attribute.write(type, values.data());
}

void
Hdf5::addMetaData(H5::DataSet &loc, const char *name,
                  const std::vector<std::string> &values)
{
    std::vector<const char *> cstrs(values.size());
    for (int i = 0; i < values.size(); ++i)
        cstrs[i] = values[i].c_str();

    addMetaData(loc, name, cstrs);
}

void
Hdf5::addMetaData(H5::DataSet &loc, const char *name,
                  const std::string &value)
{
    H5::StrType type(H5::PredType::C_S1, value.length() + 1);
    hsize_t dims[1] = { 1, };
    H5::DataSpace space(1, dims);
    H5::Attribute attribute = loc.createAttribute(name, type, space);
    attribute.write(type, value.c_str());
}

void
Hdf5::addMetaData(H5::DataSet &loc, const char *name, double value)
{
    hsize_t dims[1] = { 1, };
    H5::DataSpace space(1, dims);
    H5::Attribute attribute = loc.createAttribute(
        name, H5::PredType::NATIVE_DOUBLE, space);
    attribute.write(H5::PredType::NATIVE_DOUBLE, &value);
}


std::unique_ptr<Output>
initHDF5(const std::string &filename, unsigned chunking,
         bool desc, bool formulas)
{
    return  std::unique_ptr<Output>(
        new Hdf5(simout.resolve(filename), chunking, desc, formulas));
}

}; // namespace Stats
