/*
 *  Copyright 2004 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/pc/rtcpmuxfilter.h"

#include "webrtc/rtc_base/logging.h"

namespace cricket {

RtcpMuxFilter::RtcpMuxFilter() : state_(ST_INIT), offer_enable_(false) {
}

bool RtcpMuxFilter::IsFullyActive() const {
  return state_ == ST_ACTIVE;
}

bool RtcpMuxFilter::IsProvisionallyActive() const {
  return state_ == ST_SENTPRANSWER || state_ == ST_RECEIVEDPRANSWER;
}

bool RtcpMuxFilter::IsActive() const {
  return IsFullyActive() || IsProvisionallyActive();
}

void RtcpMuxFilter::SetActive() {
  state_ = ST_ACTIVE;
}

bool RtcpMuxFilter::SetOffer(bool offer_enable, ContentSource src) {
  if (state_ == ST_ACTIVE) {
    // Fail if we try to deactivate and no-op if we try and activate.
    return offer_enable;
  }

  if (!ExpectOffer(offer_enable, src)) {
    LOG(LS_ERROR) << "Invalid state for change of RTCP mux offer";
    return false;
  }

  offer_enable_ = offer_enable;
  state_ = (src == CS_LOCAL) ? ST_SENTOFFER : ST_RECEIVEDOFFER;
  return true;
}

bool RtcpMuxFilter::SetProvisionalAnswer(bool answer_enable,
                                         ContentSource src) {
  if (state_ == ST_ACTIVE) {
    // Fail if we try to deactivate and no-op if we try and activate.
    return answer_enable;
  }

  if (!ExpectAnswer(src)) {
    LOG(LS_ERROR) << "Invalid state for RTCP mux provisional answer";
    return false;
  }

  if (offer_enable_) {
    if (answer_enable) {
      if (src == CS_REMOTE)
        state_ = ST_RECEIVEDPRANSWER;
      else  // CS_LOCAL
        state_ = ST_SENTPRANSWER;
    } else {
      // The provisional answer doesn't want to use RTCP mux.
      // Go back to the original state after the offer was set and wait for next
      // provisional or final answer.
      if (src == CS_REMOTE)
        state_ = ST_SENTOFFER;
      else  // CS_LOCAL
        state_ = ST_RECEIVEDOFFER;
    }
  } else if (answer_enable) {
    // If the offer didn't specify RTCP mux, the answer shouldn't either.
    LOG(LS_WARNING) << "Invalid parameters in RTCP mux provisional answer";
    return false;
  }

  return true;
}

bool RtcpMuxFilter::SetAnswer(bool answer_enable, ContentSource src) {
  if (state_ == ST_ACTIVE) {
    // Fail if we try to deactivate and no-op if we try and activate.
    return answer_enable;
  }

  if (!ExpectAnswer(src)) {
    LOG(LS_ERROR) << "Invalid state for RTCP mux answer";
    return false;
  }

  if (offer_enable_ && answer_enable) {
    state_ = ST_ACTIVE;
  } else if (answer_enable) {
    // If the offer didn't specify RTCP mux, the answer shouldn't either.
    LOG(LS_WARNING) << "Invalid parameters in RTCP mux answer";
    return false;
  } else {
    state_ = ST_INIT;
  }
  return true;
}

bool RtcpMuxFilter::ExpectOffer(bool offer_enable, ContentSource source) {
  return ((state_ == ST_INIT) ||
          (state_ == ST_ACTIVE && offer_enable == offer_enable_) ||
          (state_ == ST_SENTOFFER && source == CS_LOCAL) ||
          (state_ == ST_RECEIVEDOFFER && source == CS_REMOTE));
}

bool RtcpMuxFilter::ExpectAnswer(ContentSource source) {
  return ((state_ == ST_SENTOFFER && source == CS_REMOTE) ||
          (state_ == ST_RECEIVEDOFFER && source == CS_LOCAL) ||
          (state_ == ST_SENTPRANSWER && source == CS_LOCAL) ||
          (state_ == ST_RECEIVEDPRANSWER && source == CS_REMOTE));
}

}  // namespace cricket
