//===-- rosa/agent/State.hpp ------------------------------------*- C++ -*-===//
//
//                                 The RoSA Framework
//
// Distributed under the terms and conditions of the Boost Software License 1.0.
// See accompanying file LICENSE.
//
// If you did not receive a copy of the license file, see
// http://www.boost.org/LICENSE_1_0.txt.
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/agent/State.hpp
///
/// \author Maximilian Götzinger (maximilian.goetzinger@tuwien.ac.at)
///
/// \date 2019
///
/// \brief Definition of *state* *functionality*.
///
//===----------------------------------------------------------------------===//

#ifndef ROSA_AGENT_STATE_HPP
#define ROSA_AGENT_STATE_HPP

#include "rosa/agent/Functionality.h"
//#include "rosa/agent/FunctionAbstractions.hpp"
//#include "rosa/agent/History.hpp"

#include "rosa/support/debug.hpp"

#include <stdint.h>

//#include <vector>

namespace rosa {
namespace agent {

/// State conditions defining how the condition of a \c rosa::agent::State is
/// saved in \c rosa::agent::StateInformation.
enum StateConditions : uint8_t {
  /*
UNKNOWN = 0,        ///< The state is unknown
STABLE = 1,         ///< The state is stable
DRIFTING_UP = 2,    ///< The state is drifting up
DRIFTING_DN = 3,    ///< The state is drifting down
MALFUNCTIONING = 4 ///< Malfunction
*/
  UNKNOWN = 0,       ///< The state is unknown
  STABLE = 1,        ///< The state is stable
  DRIFTING = 2,      ///< The state is drifting
  MALFUNCTIONING = 3 ///< Malfunction
};

template <typename CONFDATATYPE> struct StateInformation {
  // Make sure the actual type arguments are matching our expectations.
  STATIC_ASSERT((std::is_arithmetic<CONFDATATYPE>::value),
                "confidence type is not to arithmetic");
  /// The StateID stores the ID of the state.
  unsigned int StateID;
  /// The StateCondition shows the condition of a state (stable, drifting, or
  /// unknown)
  StateConditions StateCondition;
  /// The StateIsValid shows whether a state is valid or invalid. In this
  /// context, valid means that enough samples which are in close proximitry
  /// have been inserted into the state.
  bool StateIsValid;
  /// The StateJustGotValid shows whether a state got valid (toggled from
  /// invalid to valid) during the current inserted sample.
  bool StateJustGotValid;
  /// The StateIsValidAfterReentrance shows whether a state is valid after the
  /// variable changed back to it again.
  bool StateIsValidAfterReentrance;

  /// TODO: describe
  CONFDATATYPE ConfidenceStateIsValid;
  CONFDATATYPE ConfidenceStateIsInvalid;

  CONFDATATYPE ConfidenceStateIsStable;
  CONFDATATYPE ConfidenceStateIsDrifting;
};

template <typename INDATATYPE, typename CONFDATATYPE, typename PROCDATATYPE>
class State : public Functionality {

  // Make sure the actual type arguments are matching our expectations.
  STATIC_ASSERT((std::is_arithmetic<INDATATYPE>::value),
                "input data type not arithmetic");
  STATIC_ASSERT((std::is_arithmetic<CONFDATATYPE>::value),
                "confidence abstraction type is not to arithmetic");
  STATIC_ASSERT((std::is_arithmetic<PROCDATATYPE>::value),
                "process type is not to arithmetic");

protected:
};

} // End namespace agent
} // End namespace rosa

#endif // ROSA_AGENT_SIGNALSTATEDETECTOR_HPP
