/*
 * libjingle
 * Copyright 2011 Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "talk/media/base/streamparams.h"

#include <list>
#include <sstream>

namespace {

// NOTE: There is no check here for duplicate streams, so check before
// adding.
void AddStream(std::vector<cricket::StreamParams>* streams,
               const cricket::StreamParams& stream) {
  streams->push_back(stream);
}

}

namespace cricket {

const char kFecSsrcGroupSemantics[] = "FEC";
const char kFidSsrcGroupSemantics[] = "FID";
const char kSimSsrcGroupSemantics[] = "SIM";

bool MediaStreams::GetAudioStream(
    const StreamSelector& selector, StreamParams* stream) {
  return GetStream(audio_, selector, stream);
}

bool MediaStreams::GetVideoStream(
    const StreamSelector& selector, StreamParams* stream) {
  return GetStream(video_, selector, stream);
}

bool MediaStreams::GetDataStream(
    const StreamSelector& selector, StreamParams* stream) {
  return GetStream(data_, selector, stream);
}

void MediaStreams::CopyFrom(const MediaStreams& streams) {
  audio_ = streams.audio_;
  video_ = streams.video_;
  data_ = streams.data_;
}

void MediaStreams::AddAudioStream(const StreamParams& stream) {
  AddStream(&audio_, stream);
}

void MediaStreams::AddVideoStream(const StreamParams& stream) {
  AddStream(&video_, stream);
}

void MediaStreams::AddDataStream(const StreamParams& stream) {
  AddStream(&data_, stream);
}

bool MediaStreams::RemoveAudioStream(
    const StreamSelector& selector) {
  return RemoveStream(&audio_, selector);
}

bool MediaStreams::RemoveVideoStream(
    const StreamSelector& selector) {
  return RemoveStream(&video_, selector);
}

bool MediaStreams::RemoveDataStream(
    const StreamSelector& selector) {
  return RemoveStream(&data_, selector);
}

static std::string SsrcsToString(const std::vector<uint32>& ssrcs) {
  std::ostringstream ost;
  ost << "ssrcs:[";
  for (std::vector<uint32>::const_iterator it = ssrcs.begin();
       it != ssrcs.end(); ++it) {
    if (it != ssrcs.begin()) {
      ost << ",";
    }
    ost << *it;
  }
  ost << "]";
  return ost.str();
}

bool SsrcGroup::has_semantics(const std::string& semantics_in) const {
  return (semantics == semantics_in && ssrcs.size() > 0);
}

std::string SsrcGroup::ToString() const {
  std::ostringstream ost;
  ost << "{";
  ost << "semantics:" << semantics << ";";
  ost << SsrcsToString(ssrcs);
  ost << "}";
  return ost.str();
}

std::string StreamParams::ToString() const {
  std::ostringstream ost;
  ost << "{";
  if (!groupid.empty()) {
    ost << "groupid:" << groupid << ";";
  }
  if (!id.empty()) {
    ost << "id:" << id << ";";
  }
  ost << SsrcsToString(ssrcs) << ";";
  ost << "ssrc_groups:";
  for (std::vector<SsrcGroup>::const_iterator it = ssrc_groups.begin();
       it != ssrc_groups.end(); ++it) {
    if (it != ssrc_groups.begin()) {
      ost << ",";
    }
    ost << it->ToString();
  }
  ost << ";";
  if (!type.empty()) {
    ost << "type:" << type << ";";
  }
  if (!display.empty()) {
    ost << "display:" << display << ";";
  }
  if (!cname.empty()) {
    ost << "cname:" << cname << ";";
  }
  if (!sync_label.empty()) {
    ost << "sync_label:" << sync_label;
  }
  ost << "}";
  return ost.str();
}
void StreamParams::GetPrimarySsrcs(std::vector<uint32>* ssrcs) const {
  const SsrcGroup* sim_group = get_ssrc_group(kSimSsrcGroupSemantics);
  if (sim_group == NULL) {
    ssrcs->push_back(first_ssrc());
  } else {
    for (size_t i = 0; i < sim_group->ssrcs.size(); ++i) {
      ssrcs->push_back(sim_group->ssrcs[i]);
    }
  }
}

void StreamParams::GetFidSsrcs(const std::vector<uint32>& primary_ssrcs,
                               std::vector<uint32>* fid_ssrcs) const {
  for (size_t i = 0; i < primary_ssrcs.size(); ++i) {
    uint32 fid_ssrc;
    if (GetFidSsrc(primary_ssrcs[i], &fid_ssrc)) {
      fid_ssrcs->push_back(fid_ssrc);
    }
  }
}

bool StreamParams::AddSecondarySsrc(const std::string& semantics,
                                    uint32 primary_ssrc,
                                    uint32 secondary_ssrc) {
  if (!has_ssrc(primary_ssrc)) {
    return false;
  }

  ssrcs.push_back(secondary_ssrc);
  std::vector<uint32> ssrc_vector;
  ssrc_vector.push_back(primary_ssrc);
  ssrc_vector.push_back(secondary_ssrc);
  SsrcGroup ssrc_group = SsrcGroup(semantics, ssrc_vector);
  ssrc_groups.push_back(ssrc_group);
  return true;
}

bool StreamParams::GetSecondarySsrc(const std::string& semantics,
                                    uint32 primary_ssrc,
                                    uint32* secondary_ssrc) const {
  for (std::vector<SsrcGroup>::const_iterator it = ssrc_groups.begin();
       it != ssrc_groups.end(); ++it) {
    if (it->has_semantics(semantics) &&
          it->ssrcs.size() >= 2 &&
          it->ssrcs[0] == primary_ssrc) {
      *secondary_ssrc = it->ssrcs[1];
      return true;
    }
  }
  return false;
}

bool GetStream(const StreamParamsVec& streams,
               const StreamSelector& selector,
               StreamParams* stream_out) {
  for (StreamParamsVec::const_iterator stream = streams.begin();
       stream != streams.end(); ++stream) {
    if (selector.Matches(*stream)) {
      if (stream_out != NULL) {
        *stream_out = *stream;
      }
      return true;
    }
  }
  return false;
}

bool GetStreamBySsrc(const StreamParamsVec& streams, uint32 ssrc,
                     StreamParams* stream_out) {
  return GetStream(streams, StreamSelector(ssrc), stream_out);
}

bool GetStreamByIds(const StreamParamsVec& streams,
                    const std::string& groupid,
                    const std::string& id,
                    StreamParams* stream_out) {
  return GetStream(streams, StreamSelector(groupid, id), stream_out);
}

bool RemoveStream(StreamParamsVec* streams,
                  const StreamSelector& selector) {
  bool ret = false;
  for (StreamParamsVec::iterator stream = streams->begin();
       stream != streams->end(); ) {
    if (selector.Matches(*stream)) {
      stream = streams->erase(stream);
      ret = true;
    } else {
      ++stream;
    }
  }
  return ret;
}

bool RemoveStreamBySsrc(StreamParamsVec* streams, uint32 ssrc) {
  return RemoveStream(streams, StreamSelector(ssrc));
}

bool RemoveStreamByIds(StreamParamsVec* streams,
                       const std::string& groupid,
                       const std::string& id) {
  return RemoveStream(streams, StreamSelector(groupid, id));
}

bool IsOneSsrcStream(const StreamParams& sp) {
  if (sp.ssrcs.size() == 1 && sp.ssrc_groups.empty()) {
    return true;
  }
  if (sp.ssrcs.size() == 2) {
    const SsrcGroup* fid_group = sp.get_ssrc_group(kFidSsrcGroupSemantics);
    if (fid_group != NULL) {
      return (sp.ssrcs == fid_group->ssrcs);
    }
  }
  return false;
}

static void RemoveFirst(std::list<uint32>* ssrcs, uint32 value) {
  std::list<uint32>::iterator it =
      std::find(ssrcs->begin(), ssrcs->end(), value);
  if (it != ssrcs->end()) {
    ssrcs->erase(it);
  }
}

bool IsSimulcastStream(const StreamParams& sp) {
  const SsrcGroup* const sg = sp.get_ssrc_group(kSimSsrcGroupSemantics);
  if (sg == NULL || sg->ssrcs.size() < 2) {
    return false;
  }
  // Start with all StreamParams SSRCs. Remove simulcast SSRCs (from sg) and
  // RTX SSRCs. If we still have SSRCs left, we don't know what they're for.
  // Also we remove first-found SSRCs only. So duplicates should lead to errors.
  std::list<uint32> sp_ssrcs(sp.ssrcs.begin(), sp.ssrcs.end());
  for (size_t i = 0; i < sg->ssrcs.size(); ++i) {
    RemoveFirst(&sp_ssrcs, sg->ssrcs[i]);
  }
  for (size_t i = 0; i < sp.ssrc_groups.size(); ++i) {
    const SsrcGroup& group = sp.ssrc_groups[i];
    if (group.semantics.compare(kFidSsrcGroupSemantics) != 0 ||
        group.ssrcs.size() != 2) {
      continue;
    }
    RemoveFirst(&sp_ssrcs, group.ssrcs[1]);
  }
  // If there's SSRCs left that we don't know how to handle, we bail out.
  return sp_ssrcs.size() == 0;
}

}  // namespace cricket
