/*
 *  Copyright 2013 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/webrtc_session_description_factory.h"

#include <cstddef>
#include <cstdint>
#include <memory>
#include <optional>
#include <queue>
#include <string>
#include <utility>
#include <vector>

#include "absl/algorithm/container.h"
#include "absl/functional/any_invocable.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "api/environment/environment.h"
#include "api/jsep.h"
#include "api/peer_connection_interface.h"
#include "api/rtc_error.h"
#include "api/scoped_refptr.h"
#include "api/sequence_checker.h"
#include "api/task_queue/pending_task_safety_flag.h"
#include "pc/codec_vendor.h"
#include "pc/connection_context.h"
#include "pc/media_options.h"
#include "pc/media_session.h"
#include "pc/sdp_state_provider.h"
#include "pc/session_description.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/rtc_certificate.h"
#include "rtc_base/rtc_certificate_generator.h"
#include "rtc_base/ssl_identity.h"
#include "rtc_base/ssl_stream_adapter.h"
#include "rtc_base/thread.h"

namespace webrtc {
namespace {
const char kFailedDueToIdentityFailed[] =
    " failed because DTLS identity request failed";
const char kFailedDueToSessionShutdown[] =
    " failed because the session was shut down";

const uint64_t kInitSessionVersion = 2;

// Check that each sender has a unique ID.
bool ValidMediaSessionOptions(const MediaSessionOptions& session_options) {
  std::vector<SenderOptions> sorted_senders;
  for (const MediaDescriptionOptions& media_description_options :
       session_options.media_description_options) {
    sorted_senders.insert(sorted_senders.end(),
                          media_description_options.sender_options.begin(),
                          media_description_options.sender_options.end());
  }
  absl::c_sort(sorted_senders,
               [](const SenderOptions& sender1, const SenderOptions& sender2) {
                 return sender1.track_id < sender2.track_id;
               });
  return absl::c_adjacent_find(
             sorted_senders,
             [](const SenderOptions& sender1, const SenderOptions& sender2) {
               return sender1.track_id == sender2.track_id;
             }) == sorted_senders.end();
}
}  // namespace

// static
void WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription(
    const SessionDescriptionInterface* source_desc,
    absl::string_view content_name,
    SessionDescriptionInterface* dest_desc) {
  if (!source_desc) {
    return;
  }
  const ContentInfos& contents = source_desc->description()->contents();
  const ContentInfo* cinfo =
      source_desc->description()->GetContentByName(content_name);
  if (!cinfo) {
    return;
  }
  size_t mediasection_index = static_cast<int>(cinfo - &contents[0]);
  const IceCandidateCollection* source_candidates =
      source_desc->candidates(mediasection_index);
  const IceCandidateCollection* dest_candidates =
      dest_desc->candidates(mediasection_index);
  if (!source_candidates || !dest_candidates) {
    return;
  }
  for (size_t n = 0; n < source_candidates->count(); ++n) {
    const IceCandidate* new_candidate = source_candidates->at(n);
    if (!dest_candidates->HasCandidate(new_candidate)) {
      dest_desc->AddCandidate(source_candidates->at(n));
    }
  }
}

WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory(
    ConnectionContext* context,
    const SdpStateProvider* sdp_info,
    const std::string& session_id,
    bool dtls_enabled,
    std::unique_ptr<RTCCertificateGeneratorInterface> cert_generator,
    scoped_refptr<RTCCertificate> certificate,
    absl::AnyInvocable<void(scoped_refptr<RTCCertificate>) &&>
        on_certificate_ready,
    CodecLookupHelper* codec_lookup_helper,
    const Environment& env)
    : signaling_thread_(context->signaling_thread()),
      transport_desc_factory_(env.field_trials()),
      session_desc_factory_(env,
                            context->ssrc_generator(),
                            &transport_desc_factory_,
                            context->sctp_transport_factory(),
                            codec_lookup_helper),
      // RFC 4566 suggested a Network Time Protocol (NTP) format timestamp
      // as the session id and session version. To simplify, it should be fine
      // to just use a random number as session id and start version from
      // `kInitSessionVersion`.
      session_version_(kInitSessionVersion),
      cert_generator_(dtls_enabled ? std::move(cert_generator) : nullptr),
      sdp_info_(sdp_info),
      session_id_(session_id),
      env_(env),
      certificate_request_state_(CERTIFICATE_NOT_NEEDED) {
  RTC_DCHECK(signaling_thread_);

  if (!dtls_enabled) {
    RTC_LOG(LS_INFO) << "DTLS-SRTP disabled";
    transport_desc_factory_.SetInsecureForTesting();
    return;
  }
  RTC_DCHECK(on_certificate_ready);
  if (certificate) {
    // Use `certificate`.
    certificate_request_state_ = CERTIFICATE_WAITING;

    RTC_LOG(LS_VERBOSE) << "DTLS-SRTP enabled; has certificate parameter.";
    RTC_LOG(LS_INFO) << "Using certificate supplied to the constructor.";
    std::move(on_certificate_ready)(certificate);
    SetCertificate(certificate);
    return;
  }
  // Generate certificate.
  RTC_DCHECK(cert_generator_);
  certificate_request_state_ = CERTIFICATE_WAITING;

  auto callback = [this, flag = safety_.flag(),
                   on_certificate_ready = std::move(on_certificate_ready)](
                      scoped_refptr<RTCCertificate> certificate) mutable {
    if (!flag->alive()) {
      return;
    }
    if (certificate) {
      std::move(on_certificate_ready)(certificate);
      SetCertificate(std::move(certificate));
    } else {
      OnCertificateRequestFailed();
    }
  };

  KeyParams key_params = KeyParams();
  RTC_LOG(LS_VERBOSE)
      << "DTLS-SRTP enabled; sending DTLS identity request (key type: "
      << key_params.type() << ").";

  // Request certificate. This happens asynchronously on a different thread.
  cert_generator_->GenerateCertificateAsync(key_params, std::nullopt,
                                            std::move(callback));
}

WebRtcSessionDescriptionFactory::~WebRtcSessionDescriptionFactory() {
  RTC_DCHECK_RUN_ON(signaling_thread_);
  RTC_DCHECK_DISALLOW_THREAD_BLOCKING_CALLS();

  // Fail any requests that were asked for before identity generation completed.
  FailPendingRequests(kFailedDueToSessionShutdown);

  // Process all pending notifications. If we don't do this, requests will
  // linger and not know they succeeded or failed.
  // All tasks that suppose to run them are protected with weak_factory_ and
  // will be cancelled. If we don't protect them, they might trigger after peer
  // connection is destroyed, which might be surprising.
  std::queue<absl::AnyInvocable<void() &&>> callbacks = std::move(callbacks_);
  while (!callbacks.empty()) {
    auto callback = std::move(callbacks.front());
    callbacks.pop();
    std::move(callback)();
  }
}

void WebRtcSessionDescriptionFactory::CreateOffer(
    CreateSessionDescriptionObserver* observer,
    const PeerConnectionInterface::RTCOfferAnswerOptions& options,
    const MediaSessionOptions& session_options) {
  RTC_LOG_THREAD_BLOCK_COUNT();
  RTC_DCHECK_RUN_ON(signaling_thread_);
  std::string error = "CreateOffer";
  if (certificate_request_state_ == CERTIFICATE_FAILED) {
    error += kFailedDueToIdentityFailed;
    PostCreateSessionDescriptionFailed(
        observer, RTCError(RTCErrorType::INTERNAL_ERROR, std::move(error)));
    return;
  }

  if (!ValidMediaSessionOptions(session_options)) {
    error += " called with invalid session options";
    PostCreateSessionDescriptionFailed(
        observer, RTCError(RTCErrorType::INTERNAL_ERROR, std::move(error)));
    return;
  }

  CreateSessionDescriptionRequest request(
      CreateSessionDescriptionRequest::kOffer, observer, session_options);
  if (certificate_request_state_ == CERTIFICATE_WAITING) {
    create_session_description_requests_.push(request);
  } else {
    RTC_DCHECK(certificate_request_state_ == CERTIFICATE_SUCCEEDED ||
               certificate_request_state_ == CERTIFICATE_NOT_NEEDED);
    InternalCreateOffer(request);
  }
}

void WebRtcSessionDescriptionFactory::CreateAnswer(
    CreateSessionDescriptionObserver* observer,
    const MediaSessionOptions& session_options) {
  RTC_LOG_THREAD_BLOCK_COUNT();
  std::string error = "CreateAnswer";
  if (certificate_request_state_ == CERTIFICATE_FAILED) {
    error += kFailedDueToIdentityFailed;
    PostCreateSessionDescriptionFailed(
        observer, RTCError(RTCErrorType::INTERNAL_ERROR, std::move(error)));
    return;
  }
  if (!sdp_info_->remote_description()) {
    error += " can't be called before SetRemoteDescription.";
    PostCreateSessionDescriptionFailed(
        observer, RTCError(RTCErrorType::INTERNAL_ERROR, std::move(error)));
    return;
  }
  if (sdp_info_->remote_description()->GetType() != SdpType::kOffer) {
    error += " failed because remote_description is not an offer.";
    PostCreateSessionDescriptionFailed(
        observer, RTCError(RTCErrorType::INTERNAL_ERROR, std::move(error)));
    return;
  }

  if (!ValidMediaSessionOptions(session_options)) {
    error += " called with invalid session options.";
    PostCreateSessionDescriptionFailed(
        observer, RTCError(RTCErrorType::INTERNAL_ERROR, std::move(error)));
    return;
  }

  CreateSessionDescriptionRequest request(
      CreateSessionDescriptionRequest::kAnswer, observer, session_options);
  if (certificate_request_state_ == CERTIFICATE_WAITING) {
    create_session_description_requests_.push(request);
  } else {
    RTC_DCHECK(certificate_request_state_ == CERTIFICATE_SUCCEEDED ||
               certificate_request_state_ == CERTIFICATE_NOT_NEEDED);
    InternalCreateAnswer(request);
  }
}

void WebRtcSessionDescriptionFactory::InternalCreateOffer(
    CreateSessionDescriptionRequest request) {
  if (sdp_info_->local_description()) {
    // If the needs-ice-restart flag is set as described by JSEP, we should
    // generate an offer with a new ufrag/password to trigger an ICE restart.
    for (MediaDescriptionOptions& options :
         request.options.media_description_options) {
      if (sdp_info_->NeedsIceRestart(options.mid)) {
        options.transport_options.ice_restart = true;
      }
    }
  }

  auto result = session_desc_factory_.CreateOfferOrError(
      request.options, sdp_info_->local_description()
                           ? sdp_info_->local_description()->description()
                           : nullptr);
  if (!result.ok()) {
    PostCreateSessionDescriptionFailed(request.observer.get(), result.error());
    return;
  }
  std::unique_ptr<SessionDescription> desc = std::move(result.value());
  RTC_CHECK(desc);

  // RFC 3264
  // When issuing an offer that modifies the session,
  // the "o=" line of the new SDP MUST be identical to that in the
  // previous SDP, except that the version in the origin field MUST
  // increment by one from the previous SDP.

  // Just increase the version number by one each time when a new offer
  // is created regardless if it's identical to the previous one or not.
  // The `session_version_` is a uint64_t, the wrap around should not happen.
  RTC_DCHECK(session_version_ + 1 > session_version_);
  auto offer = SessionDescriptionInterface::Create(
      SdpType::kOffer, std::move(desc), session_id_,
      absl::StrCat(session_version_++), {},
      {.use_wildcard =
           env_.field_trials().IsEnabled("WebRTC-UseWildcardInSdp")});
  if (sdp_info_->local_description()) {
    for (const MediaDescriptionOptions& options :
         request.options.media_description_options) {
      if (!options.transport_options.ice_restart) {
        CopyCandidatesFromSessionDescription(sdp_info_->local_description(),
                                             options.mid, offer.get());
      }
    }
  }
  PostCreateSessionDescriptionSucceeded(request.observer.get(),
                                        std::move(offer));
}

void WebRtcSessionDescriptionFactory::InternalCreateAnswer(
    CreateSessionDescriptionRequest request) {
  if (sdp_info_->remote_description()) {
    for (MediaDescriptionOptions& options :
         request.options.media_description_options) {
      // According to http://tools.ietf.org/html/rfc5245#section-9.2.1.1
      // an answer should also contain new ICE ufrag and password if an offer
      // has been received with new ufrag and password.
      options.transport_options.ice_restart =
          sdp_info_->IceRestartPending(options.mid);
      // We should pass the current DTLS role to the transport description
      // factory, if there is already an existing ongoing session.
      std::optional<SSLRole> dtls_role = sdp_info_->GetDtlsRole(options.mid);
      if (dtls_role) {
        options.transport_options.prefer_passive_role =
            (SSL_SERVER == *dtls_role);
      }
    }
  }

  auto result = session_desc_factory_.CreateAnswerOrError(
      sdp_info_->remote_description()
          ? sdp_info_->remote_description()->description()
          : nullptr,
      request.options,
      sdp_info_->local_description()
          ? sdp_info_->local_description()->description()
          : nullptr);
  if (!result.ok()) {
    PostCreateSessionDescriptionFailed(request.observer.get(), result.error());
    return;
  }
  std::unique_ptr<SessionDescription> desc = std::move(result.value());
  RTC_CHECK(desc);

  // RFC 3264
  // If the answer is different from the offer in any way (different IP
  // addresses, ports, etc.), the origin line MUST be different in the answer.
  // In that case, the version number in the "o=" line of the answer is
  // unrelated to the version number in the o line of the offer.
  // Get a new version number by increasing the `session_version_answer_`.
  // The `session_version_` is a uint64_t, the wrap around should not happen.
  RTC_DCHECK(session_version_ + 1 > session_version_);
  auto answer = SessionDescriptionInterface::Create(
      SdpType::kAnswer, std::move(desc), session_id_,
      absl::StrCat(session_version_++), {},
      {.use_wildcard =
           env_.field_trials().IsEnabled("WebRTC-UseWildcardInSdp")});
  if (sdp_info_->local_description()) {
    // Include all local ICE candidates in the SessionDescription unless
    // the remote peer has requested an ICE restart.
    for (const MediaDescriptionOptions& options :
         request.options.media_description_options) {
      if (!options.transport_options.ice_restart) {
        CopyCandidatesFromSessionDescription(sdp_info_->local_description(),
                                             options.mid, answer.get());
      }
    }
  }
  PostCreateSessionDescriptionSucceeded(request.observer.get(),
                                        std::move(answer));
}

void WebRtcSessionDescriptionFactory::FailPendingRequests(
    const std::string& reason) {
  RTC_DCHECK_RUN_ON(signaling_thread_);
  while (!create_session_description_requests_.empty()) {
    const CreateSessionDescriptionRequest& request =
        create_session_description_requests_.front();
    PostCreateSessionDescriptionFailed(
        request.observer.get(),
        RTCError(RTCErrorType::INTERNAL_ERROR,
                 ((request.type == CreateSessionDescriptionRequest::kOffer)
                      ? "CreateOffer"
                      : "CreateAnswer") +
                     reason));
    create_session_description_requests_.pop();
  }
}

void WebRtcSessionDescriptionFactory::PostCreateSessionDescriptionFailed(
    CreateSessionDescriptionObserver* observer,
    RTCError error) {
  Post([observer = scoped_refptr<CreateSessionDescriptionObserver>(observer),
        error]() mutable { observer->OnFailure(error); });
  RTC_LOG(LS_ERROR) << "CreateSessionDescription failed: " << error.message();
}

void WebRtcSessionDescriptionFactory::PostCreateSessionDescriptionSucceeded(
    CreateSessionDescriptionObserver* observer,
    std::unique_ptr<SessionDescriptionInterface> description) {
  description->RelinquishThreadOwnership();
  Post([observer = scoped_refptr<CreateSessionDescriptionObserver>(observer),
        description = std::move(description)]() mutable {
    observer->OnSuccess(description.release());
  });
}

void WebRtcSessionDescriptionFactory::Post(
    absl::AnyInvocable<void() &&> callback) {
  RTC_DCHECK_RUN_ON(signaling_thread_);
  callbacks_.push(std::move(callback));
  signaling_thread_->PostTask(SafeTask(safety_.flag(), [this] {
    RTC_DCHECK(!callbacks_.empty());
    auto callback = std::move(callbacks_.front());
    callbacks_.pop();
    std::move(callback)();
  }));
}

void WebRtcSessionDescriptionFactory::OnCertificateRequestFailed() {
  RTC_DCHECK_RUN_ON(signaling_thread_);

  RTC_LOG(LS_ERROR) << "Asynchronous certificate generation request failed.";
  certificate_request_state_ = CERTIFICATE_FAILED;

  FailPendingRequests(kFailedDueToIdentityFailed);
}

void WebRtcSessionDescriptionFactory::SetCertificate(
    scoped_refptr<RTCCertificate> certificate) {
  RTC_DCHECK(certificate);
  RTC_LOG(LS_VERBOSE) << "Setting new certificate.";

  certificate_request_state_ = CERTIFICATE_SUCCEEDED;

  transport_desc_factory_.set_certificate(std::move(certificate));

  while (!create_session_description_requests_.empty()) {
    if (create_session_description_requests_.front().type ==
        CreateSessionDescriptionRequest::kOffer) {
      InternalCreateOffer(create_session_description_requests_.front());
    } else {
      InternalCreateAnswer(create_session_description_requests_.front());
    }
    create_session_description_requests_.pop();
  }
}

}  // namespace webrtc
