text: /*
  ** Copyright 2014-2015 Centreon
  **
  ** Licensed under the Apache License, Version 2.0 (the "License");
  ** you may not use this file except in compliance with the License.
  ** You may obtain a copy of the License at
  **
  **     http://www.apache.org/licenses/LICENSE-2.0
  **
  ** Unless required by applicable law or agreed to in writing, software
  ** distributed under the License is distributed on an "AS IS" BASIS,
  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ** See the License for the specific language governing permissions and
  ** limitations under the License.
  **
  ** For more information : contact@centreon.com
  */
  
  #include <ctime>
  #include <QMutexLocker>
  #include <QSqlQuery>
  #include <QSqlError>
  #include "com/centreon/broker/bam/availability_builder.hh"
  #include "com/centreon/broker/exceptions/msg.hh"
  #include "com/centreon/broker/logging/logging.hh"
  
  using namespace com::centreon::broker;
  using namespace com::centreon::broker::bam;
  
  /**
   *  Constructor.
   *
   *  @param[in] ending_point    The point from when the builder should stop to build the availability.
   *  @param[in] starting_point  The point from when the builder should build the availability.
   */
  availability_builder::availability_builder(
                          time_t ending_point,
                          time_t starting_point /* = 0 */)
    : _start(starting_point),
      _end(ending_point),
      _available(0),
      _unavailable(0),
      _degraded(0),
      _unknown(0),
      _downtime(0),
      _alert_unavailable_opened(0),
      _alert_degraded_opened(0),
      _alert_unknown_opened(0),
      _nb_downtime(0),
      _timeperiods_is_default(false) {}
  
  /**
   *  Destructor
   */
  availability_builder::~availability_builder() {}
  
  /**
   *  Copy constructor.
   *
   *  @param[in] other  The object to copy.
   */
  availability_builder::availability_builder(availability_builder const& other) {
    availability_builder::operator=(other);
  }
  
  /**
   *  Assignment operator.
   *
   *  @param[in] other  The object to copy.
   *
   *  @return  A reference to this object.
   */
  availability_builder& availability_builder::operator=(availability_builder const& other) {
    if (this != &other) {
      _start = other._start;
      _end = other._end;
      _available = other._available;
      _unavailable = other._unavailable;
      _degraded = other._degraded;
      _unknown = other._unknown;
      _downtime = other._downtime;
      _alert_unavailable_opened = other._alert_unavailable_opened;
      _alert_degraded_opened = other._alert_degraded_opened;
      _alert_unknown_opened = other._alert_unknown_opened;
      _nb_downtime = other._nb_downtime;
      _timeperiods_is_default = other._timeperiods_is_default;
    }
    return (*this);
  }
  
  /**
   *  Add an event to the builder.
   *
   *  @param[in] status           The status of the event.
   *  @param[in] start            The start time of the event.
   *  @param[in] end              The end of the event.
   *  @param[in] was_in_downtime  Was the event in downtime?
   *  @param[in] tp               The timeperiod of the event.
   */
  void availability_builder::add_event(
                               short status,
                               time_t start, time_t end,
                               bool was_in_downtime,
                               time::timeperiod::ptr const& tp) {
    // Check that the event was closed.
    if (end == 0)
      end = _end;
    // Check that the end of the event is not before the starting point of the
    // computing.
    if (end < _start)
      return ;
    // Check if event was opened "today".
    bool opened_today((start >= _start) && (start < _end));
    // Check that the event times are within the computed day.
    if (start < _start)
      start = _start;
    if (_end < end)
      end = _end;
  
    // Compute the sla_duration on the period.
    unsigned int sla_duration = tp->duration_intersect(start, end);
    if (sla_duration == (unsigned int)-1)
      return ;
  
    // Update the data.
    if (was_in_downtime) {
      _downtime += sla_duration;
      if (opened_today)
        ++_nb_downtime;
    }
    else {
      if (status == 0)
        _available += sla_duration;
      else if (status == 1) {
        _degraded += sla_duration;
        if (opened_today)
  	++_alert_degraded_opened;
      }
      else if (status == 2) {
        _unavailable += sla_duration;
        if (opened_today)
  	++_alert_unavailable_opened;
      }
      else {
        _unknown += sla_duration;
        if (opened_today)
  	++_alert_unknown_opened;
      }
    }
  }
  
  /**
   *  Get the duration in second when the BA was ok.
   *
   *  @return  The duration in second when the BA was ok.
   */
  int availability_builder::get_available() const {
    return (_available);
  }
  
  /**
   *  Get the duration in second when the BA was critical.
   *
   *  @return  The duration in second when the BA was critical.
   */
  int availability_builder::get_unavailable() const {
    return (_unavailable);
  }
  
  /**
   *  Get the duration in second when the BA was in a warning state.
   *
   *  @return  The duration in second when the BA was in a warning state.
   */
  int availability_builder::get_degraded() const {
    return (_degraded);
  }
  
  /**
   * Get the duration in second when the BA was in an unknown state.
   *
   * @return The duration in second when the BA was in an unknown state.
   */
  int availability_builder::get_unknown() const {
    return (_unknown);
  }
  
  /**
   *  Get the duration in second when the BA was in downtime.
   *
   *  @return  The duration in second when the BA was in downtime.
   */
  int availability_builder::get_downtime() const {
    return (_downtime);
  }
  
  /**
   *  Get the number of unavailable event opened.
   *
   *  @return  The number of unavailable event opened.
   */
  int availability_builder::get_unavailable_opened() const {
    return (_alert_unavailable_opened);
  }
  
  /**
   *  Get the number of degraded event opened.
   *
   *  @return  The number of degraded event opened.
   */
  int availability_builder::get_degraded_opened() const {
    return (_alert_degraded_opened);
  }
  
  /**
   *  Get the number of unknown event opened.
   *
   *  @return  The number of unknown event opened.
   */
  int availability_builder::get_unknown_opened() const {
    return (_alert_unknown_opened);
  }
  
  /**
   *  Get the number of downtime event opened.
   *
   *  @return  The number of downtime event opened.
   */
  int availability_builder::get_downtime_opened() const {
    return (_nb_downtime);
  }
  
  /**
   *  Set if the timeperiod is default.
   *
   *  @param[in] val  True if the timeperiod is default.
   */
  void availability_builder::set_timeperiod_is_default(bool val) {
    _timeperiods_is_default = val;
  }
  
  /**
   *  Get if the timeperiod is default.
   *
   *  @param[in] val  True if the timeperiod is default.
   */
  bool availability_builder::get_timeperiod_is_default() const {
    return (_timeperiods_is_default);
  }
  