// Copyright (C) 2021 EDF
// All Rights Reserved
// This code is published under the GNU Lesser General Public License (GNU LGPL)
#ifndef TUNNEL_H
#define TUNNEL_H
#include <memory>
#include <vector>
#include <array>
#include <StOpt/core/utils/constant.h>
#include <StOpt/core/grids/RegularSpaceGrid.h>

/* \file Tunnel.h
 * \brief Define a tunnel for storage.
 *        Permits to generate a calculation grid for Bellman values at a given date
 */

class Tunnel
{
private :

    std::vector< std::array<double, 2> > m_tunnel ; ///< min max value of tunnel for each date number
    double m_disVolume   ; ///< Discretization for volume
    std::vector<int> m_fromDateToData ; /// from a date (integer) , give position in m_tunnel to get data

public:

    /// \brief First constructor : one data by optimisation date
    /// \param p_tunnel      tunnel data by date
    /// \param p_disVolume   discretization volume for tunnel
    Tunnel(const std::vector< std::array<double, 2> > &p_tunnel,  const double   &p_disVolume);

    /// \brief Second constructor :  add a correspondance  between a date an a position in tunnel
    /// \param p_dateToPos   array such that
    ///                       - for date 0 to  p_dateToPos[0] (excluded), tunnel caracteristic is p_tunnel[0]
    ///                       - for date p_dateToPos[i] to p_dateToPos[i+1] excluded  , tunnel caracteristic is p_tunnel[i+1]
    /// \param p_tunnel      tunnel data
    /// \param p_disVolume   discretization volume for tunnel
    Tunnel(const std::vector<int>    &p_dateToPos, const std::vector< std::array<double, 2> > &p_tunnel,  const double   &p_disVolume);

    /// \brief get back back at a given date
    /// \param  p_idate   date number
    std::shared_ptr<StOpt::FullGrid> getGrid(const int &p_idate) const;

    /// \brief get last date of tunnl
    inline int getLastDate() const
    {
        return m_fromDateToData.size() - 1;
    }

    /// \brief from a date get back min and max
    /// \param p_idate date
    std::array<double, 2>  getMinMaxAtDate(const int &p_idate) const;

    /// \brief print the grid
    void print(const int &p_idate) const;
};
#endif
