// src/backend/concrete_environment.hh - Copyright 2005, 2006, University
//               of Padova, dept. of Pure and Applied
//               Mathematics
//
// This file is part of SGPEMv2.
//
// This is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// SGPEMv2 is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with SGPEMv2; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

#ifndef CONCRETE_ENVIRONMENT_HH
#define CONCRETE_ENVIRONMENT_HH 1

#include "config.h"
#include <sgpemv2/environment.hh>
#include <sgpemv2/resource.hh>
#include "dynamic_process.hh"
#include "dynamic_request.hh"
#include <sgpemv2/ready_queue.hh>


namespace sgpem
{
  class SerializeVisitor;


  ///  \brief An implementation of the Environment class
  /// Class ConcreteEnvironment implements the Environment
  /// abstract class.
  ///
  /// This implementation actually contains the collections
  /// of snapshots accessed by the function members defined
  /// in the Environment class.
  ///
  /// \see Environment
  class SG_DLLLOCAL ConcreteEnvironment : public Environment
  {

  public:
    /// \brief Standard constructor.
    /// Builds an empty environment.
    ConcreteEnvironment();

    /// \brief Copy constructor.
    /// Performs a deep copy of all structures.
    ConcreteEnvironment(const ConcreteEnvironment& c);


    /// \brief Returns an indexed set of snapshots of the processes
    /// Returns a standard vector of Process objects describing
    /// all the processes of the simulated environment at the
    /// considered instant.
    ///
    /// The Process objects returned are actually DynamicProcess
    /// objects. A downcast to DynamicProcess is guaranteed to be
    /// always safe.
    ///
    /// \return a constant set of snapshots of processes
    virtual const Processes&
    get_processes() const;



    /// \brief Non-constant version of get_processes()
    ///
    /// \return a set of snapshots of processes
    /// \see get_processes()
    virtual Processes&
    get_processes();



    /// \brief Returns an indexed set of snapshots of the resources
    /// Returns a standard map of \code int \endcode to Resource
    /// objects describing the all resources of the simulated environment
    /// at the considered instant.
    ///
    /// The set is indexed in order to allow retreiving the requested
    /// resource of a SubRequest object.
    ///
    /// Future implementation may provide a cleaner implementation, i.e.
    /// a \code get_request \endcode function member in the SubRequest
    /// class which returns the Resource object indexed.
    ///
    /// The Resource objects returned are actually DynamicResource
    /// objects. A downcast to DynamicResource is guaranteed to be
    /// always safe.
    ///
    /// \return a indexed constant set of snapshot of resources.
    /// \see DynamicSybrequest::get_resource()
    virtual const Resources&
    get_resources() const;



    /// \brief Non-constant version of get_resources()
    ///
    /// \return an indexed set of snapshots of resources
    /// \see get_resources()
    virtual Resources&
    get_resources();



    /// \brief Returns a snapshot of the current request queue for a resource.
    /// Returns a standard vector of Request objects
    /// representing the queue of ready requests of threads which
    /// are waiting for getting control of a limited-access resource.
    ///
    /// The Request objects returned are actually DynamicRequest
    /// objects. A downcast to DynamicRequest is guaranteed to be
    /// always safe.
    ///
    /// \param resource The resource the requests are for
    /// \return The current ready requests queue.
    virtual const SubRequestQueue&
    get_request_queue(resource_key_t resource_key) const;

    SubRequestQueue&
    get_request_queue(resource_key_t resource_key);



    typedef std::map<resource_key_t, SubRequestQueue> SubRequestQueues;


    /// \brief Returns the set of request queues.
    /// Returns a reference to the map from resources to subreuqest queues.
    /// It is needed by history to delete the queue associated to a deleted
    /// resource.

    SubRequestQueues&
    get_subrequest_queues();

    /// \brief Returns a snapshot of the current scheduler's ready queue.
    /// Returns a ReadyQueue object representing the queue
    /// of ready processes or ready threads, depending on the
    /// scheduling policy, which are waiting for getting control
    /// of the CPU.
    ///
    /// \return the current ready queue (constant).
    virtual const ReadyQueue&
    get_sorted_queue() const;



    /// \brief Non-constant version of get_sorted_queue()
    ///
    /// \return the current ready queue.
    /// \see get_sorted_queue()
    virtual ReadyQueue&
    get_sorted_queue();



    /// \brief The standard virtual destructor.
    /// The standard virtual destructor.
    virtual
    ~ConcreteEnvironment();


  private:

    /// \brief The container of all Resource objecs.
    /// Actually contains only DynamicResource objects.
    // resources come before processes because of
    // destruction order. See destructor implementation
    Resources _resources;

    /// \brief The container of all Process objecs.
    /// Actually contains only DynamicProcess objects.
    Processes _processes;

    /// \brief The queue of the ready schedulables
    /// Does not contain the running process.
    ReadyQueue _sched_queue;

    SubRequestQueues _sreq_queues;

  }
  ; //~ class ConcreteEnvironment

} //~ namespace sgpem

#endif
