/*
 *  Copyright 2018 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 "pc/simulcast_sdp_serializer.h"

#include <map>
#include <optional>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>

#include "absl/algorithm/container.h"
#include "absl/strings/string_view.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "rtc_base/checks.h"
#include "rtc_base/string_encode.h"
#include "rtc_base/string_to_number.h"
#include "rtc_base/strings/string_builder.h"

using cricket::RidDescription;
using cricket::RidDirection;
using cricket::SimulcastDescription;
using cricket::SimulcastLayer;
using cricket::SimulcastLayerList;

namespace webrtc {

namespace {

// delimiters
const char kDelimiterComma[] = ",";
const char kDelimiterCommaChar = ',';
const char kDelimiterEqual[] = "=";
const char kDelimiterEqualChar = '=';
const char kDelimiterSemicolon[] = ";";
const char kDelimiterSemicolonChar = ';';
const char kDelimiterSpace[] = " ";
const char kDelimiterSpaceChar = ' ';

// https://tools.ietf.org/html/draft-ietf-mmusic-sdp-simulcast-13#section-5.1
// https://tools.ietf.org/html/draft-ietf-mmusic-rid-15#section-10
const char kSimulcastPausedStream[] = "~";
const char kSimulcastPausedStreamChar = '~';
const char kSendDirection[] = "send";
const char kReceiveDirection[] = "recv";
const char kPayloadType[] = "pt";

RTCError ParseError(absl::string_view message) {
  return RTCError(RTCErrorType::SYNTAX_ERROR, message);
}

// These methods serialize simulcast according to the specification:
// https://tools.ietf.org/html/draft-ietf-mmusic-sdp-simulcast-13#section-5.1
rtc::StringBuilder& operator<<(rtc::StringBuilder& builder,
                               const SimulcastLayer& simulcast_layer) {
  if (simulcast_layer.is_paused) {
    builder << kSimulcastPausedStream;
  }
  builder << simulcast_layer.rid;
  return builder;
}

rtc::StringBuilder& operator<<(
    rtc::StringBuilder& builder,
    const std::vector<SimulcastLayer>& layer_alternatives) {
  bool first = true;
  for (const SimulcastLayer& rid : layer_alternatives) {
    if (!first) {
      builder << kDelimiterComma;
    }
    builder << rid;
    first = false;
  }
  return builder;
}

rtc::StringBuilder& operator<<(rtc::StringBuilder& builder,
                               const SimulcastLayerList& simulcast_layers) {
  bool first = true;
  for (const auto& alternatives : simulcast_layers) {
    if (!first) {
      builder << kDelimiterSemicolon;
    }
    builder << alternatives;
    first = false;
  }
  return builder;
}
// This method deserializes simulcast according to the specification:
// https://tools.ietf.org/html/draft-ietf-mmusic-sdp-simulcast-13#section-5.1
// sc-str-list  = sc-alt-list *( ";" sc-alt-list )
// sc-alt-list  = sc-id *( "," sc-id )
// sc-id-paused = "~"
// sc-id        = [sc-id-paused] rid-id
// rid-id       = 1*(alpha-numeric / "-" / "_") ; see: I-D.ietf-mmusic-rid
RTCErrorOr<SimulcastLayerList> ParseSimulcastLayerList(const std::string& str) {
  std::vector<absl::string_view> tokens =
      rtc::split(str, kDelimiterSemicolonChar);
  if (tokens.empty()) {
    return ParseError("Layer list cannot be empty.");
  }

  SimulcastLayerList result;
  for (const absl::string_view& token : tokens) {
    if (token.empty()) {
      return ParseError("Simulcast alternative layer list is empty.");
    }

    std::vector<absl::string_view> rid_tokens =
        rtc::split(token, kDelimiterCommaChar);

    if (rid_tokens.empty()) {
      return ParseError("Simulcast alternative layer list is malformed.");
    }

    std::vector<SimulcastLayer> layers;
    for (const absl::string_view& rid_token : rid_tokens) {
      if (rid_token.empty() || rid_token == kSimulcastPausedStream) {
        return ParseError("Rid must not be empty.");
      }

      bool paused = rid_token[0] == kSimulcastPausedStreamChar;
      absl::string_view rid = paused ? rid_token.substr(1) : rid_token;
      layers.push_back(SimulcastLayer(rid, paused));
    }

    result.AddLayerWithAlternatives(layers);
  }

  return std::move(result);
}

webrtc::RTCError ParseRidPayloadList(const std::string& payload_list,
                                     RidDescription* rid_description) {
  RTC_DCHECK(rid_description);
  std::vector<int>& payload_types = rid_description->payload_types;
  // Check that the description doesn't have any payload types or restrictions.
  // If the pt= field is specified, it must be first and must not repeat.
  if (!payload_types.empty()) {
    return ParseError("Multiple pt= found in RID Description.");
  }
  if (!rid_description->restrictions.empty()) {
    return ParseError("Payload list must appear first in the restrictions.");
  }

  // If the pt= field is specified, it must have a value.
  if (payload_list.empty()) {
    return ParseError("Payload list must have at least one value.");
  }

  // Tokenize the ',' delimited list
  std::vector<std::string> string_payloads;
  rtc::tokenize(payload_list, kDelimiterCommaChar, &string_payloads);
  if (string_payloads.empty()) {
    return ParseError("Payload list must have at least one value.");
  }

  for (const std::string& payload_type : string_payloads) {
    std::optional<int> value = rtc::StringToNumber<int>(payload_type);
    if (!value.has_value()) {
      return ParseError("Invalid payload type: " + payload_type);
    }

    // Check if the value already appears in the payload list.
    if (absl::c_linear_search(payload_types, value.value())) {
      return ParseError("Duplicate payload type in list: " + payload_type);
    }
    payload_types.push_back(value.value());
  }

  return RTCError::OK();
}

}  // namespace

std::string SimulcastSdpSerializer::SerializeSimulcastDescription(
    const cricket::SimulcastDescription& simulcast) const {
  rtc::StringBuilder sb;
  std::string delimiter;

  if (!simulcast.send_layers().empty()) {
    sb << kSendDirection << kDelimiterSpace << simulcast.send_layers();
    delimiter = kDelimiterSpace;
  }

  if (!simulcast.receive_layers().empty()) {
    sb << delimiter << kReceiveDirection << kDelimiterSpace
       << simulcast.receive_layers();
  }

  return sb.Release();
}

// https://tools.ietf.org/html/draft-ietf-mmusic-sdp-simulcast-13#section-5.1
// a:simulcast:<send> <streams> <recv> <streams>
// Formal Grammar
// sc-value     = ( sc-send [SP sc-recv] ) / ( sc-recv [SP sc-send] )
// sc-send      = %s"send" SP sc-str-list
// sc-recv      = %s"recv" SP sc-str-list
// sc-str-list  = sc-alt-list *( ";" sc-alt-list )
// sc-alt-list  = sc-id *( "," sc-id )
// sc-id-paused = "~"
// sc-id        = [sc-id-paused] rid-id
// rid-id       = 1*(alpha-numeric / "-" / "_") ; see: I-D.ietf-mmusic-rid
RTCErrorOr<SimulcastDescription>
SimulcastSdpSerializer::DeserializeSimulcastDescription(
    absl::string_view string) const {
  std::vector<std::string> tokens;
  rtc::tokenize(std::string(string), kDelimiterSpaceChar, &tokens);

  if (tokens.size() != 2 && tokens.size() != 4) {
    return ParseError("Must have one or two <direction, streams> pairs.");
  }

  bool bidirectional = tokens.size() == 4;  // indicates both send and recv

  // Tokens 0, 2 (if exists) should be send / recv
  if ((tokens[0] != kSendDirection && tokens[0] != kReceiveDirection) ||
      (bidirectional && tokens[2] != kSendDirection &&
       tokens[2] != kReceiveDirection) ||
      (bidirectional && tokens[0] == tokens[2])) {
    return ParseError("Valid values: send / recv.");
  }

  // Tokens 1, 3 (if exists) should be alternative layer lists
  RTCErrorOr<SimulcastLayerList> list1, list2;
  list1 = ParseSimulcastLayerList(tokens[1]);
  if (!list1.ok()) {
    return list1.MoveError();
  }

  if (bidirectional) {
    list2 = ParseSimulcastLayerList(tokens[3]);
    if (!list2.ok()) {
      return list2.MoveError();
    }
  }

  // Set the layers so that list1 is for send and list2 is for recv
  if (tokens[0] != kSendDirection) {
    std::swap(list1, list2);
  }

  // Set the layers according to which pair is send and which is recv
  // At this point if the simulcast is unidirectional then
  // either `list1` or `list2` will be in 'error' state indicating that
  // the value should not be used.
  SimulcastDescription simulcast;
  if (list1.ok()) {
    simulcast.send_layers() = list1.MoveValue();
  }

  if (list2.ok()) {
    simulcast.receive_layers() = list2.MoveValue();
  }

  return std::move(simulcast);
}

std::string SimulcastSdpSerializer::SerializeRidDescription(
    const RidDescription& rid_description) const {
  RTC_DCHECK(!rid_description.rid.empty());
  RTC_DCHECK(rid_description.direction == RidDirection::kSend ||
             rid_description.direction == RidDirection::kReceive);

  rtc::StringBuilder builder;
  builder << rid_description.rid << kDelimiterSpace
          << (rid_description.direction == RidDirection::kSend
                  ? kSendDirection
                  : kReceiveDirection);

  const auto& payload_types = rid_description.payload_types;
  const auto& restrictions = rid_description.restrictions;

  // First property is separated by ' ', the next ones by ';'.
  const char* propertyDelimiter = kDelimiterSpace;

  // Serialize any codecs in the description.
  if (!payload_types.empty()) {
    builder << propertyDelimiter << kPayloadType << kDelimiterEqual;
    propertyDelimiter = kDelimiterSemicolon;
    const char* formatDelimiter = "";
    for (int payload_type : payload_types) {
      builder << formatDelimiter << payload_type;
      formatDelimiter = kDelimiterComma;
    }
  }

  // Serialize any restrictions in the description.
  for (const auto& pair : restrictions) {
    // Serialize key=val pairs. =val part is ommitted if val is empty.
    builder << propertyDelimiter << pair.first;
    if (!pair.second.empty()) {
      builder << kDelimiterEqual << pair.second;
    }

    propertyDelimiter = kDelimiterSemicolon;
  }

  return builder.Release();
}

// https://tools.ietf.org/html/draft-ietf-mmusic-rid-15#section-10
// Formal Grammar
// rid-syntax         = %s"a=rid:" rid-id SP rid-dir
//                      [ rid-pt-param-list / rid-param-list ]
// rid-id             = 1*(alpha-numeric / "-" / "_")
// rid-dir            = %s"send" / %s"recv"
// rid-pt-param-list  = SP rid-fmt-list *( ";" rid-param )
// rid-param-list     = SP rid-param *( ";" rid-param )
// rid-fmt-list       = %s"pt=" fmt *( "," fmt )
// rid-param          = 1*(alpha-numeric / "-") [ "=" param-val ]
// param-val          = *( %x20-58 / %x60-7E )
//                      ; Any printable character except semicolon
RTCErrorOr<RidDescription> SimulcastSdpSerializer::DeserializeRidDescription(
    absl::string_view string) const {
  std::vector<std::string> tokens;
  rtc::tokenize(std::string(string), kDelimiterSpaceChar, &tokens);

  if (tokens.size() < 2) {
    return ParseError("RID Description must contain <RID> <direction>.");
  }

  if (tokens.size() > 3) {
    return ParseError("Invalid RID Description format. Too many arguments.");
  }

  if (!IsLegalRsidName(tokens[0])) {
    return ParseError("Invalid RID value: " + tokens[0] + ".");
  }

  if (tokens[1] != kSendDirection && tokens[1] != kReceiveDirection) {
    return ParseError("Invalid RID direction. Supported values: send / recv.");
  }

  RidDirection direction = tokens[1] == kSendDirection ? RidDirection::kSend
                                                       : RidDirection::kReceive;

  RidDescription rid_description(tokens[0], direction);

  // If there is a third argument it is a payload list and/or restriction list.
  if (tokens.size() == 3) {
    std::vector<std::string> restrictions;
    rtc::tokenize(tokens[2], kDelimiterSemicolonChar, &restrictions);

    // Check for malformed restriction list, such as ';' or ';;;' etc.
    if (restrictions.empty()) {
      return ParseError("Invalid RID restriction list: " + tokens[2]);
    }

    // Parse the restrictions. The payload indicator (pt) can only appear first.
    for (const std::string& restriction : restrictions) {
      std::vector<std::string> parts;
      rtc::tokenize(restriction, kDelimiterEqualChar, &parts);
      if (parts.empty() || parts.size() > 2) {
        return ParseError("Invalid format for restriction: " + restriction);
      }

      // `parts` contains at least one value and it does not contain a space.
      // Note: `parts` and other values might still contain tab, newline,
      // unprintable characters, etc. which will not generate errors here but
      // will (most-likely) be ignored by components down stream.
      if (parts[0] == kPayloadType) {
        RTCError error = ParseRidPayloadList(
            parts.size() > 1 ? parts[1] : std::string(), &rid_description);
        if (!error.ok()) {
          return std::move(error);
        }

        continue;
      }

      // Parse `parts` as a key=value pair which allows unspecified values.
      if (rid_description.restrictions.find(parts[0]) !=
          rid_description.restrictions.end()) {
        return ParseError("Duplicate restriction specified: " + parts[0]);
      }

      rid_description.restrictions[parts[0]] =
          parts.size() > 1 ? parts[1] : std::string();
    }
  }

  return std::move(rid_description);
}

}  // namespace webrtc
