/*
 *  Copyright 2020 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 "examples/androidvoip/jni/android_voip_client.h"

#include <errno.h>
#include <sys/socket.h>

#include <algorithm>
#include <map>
#include <memory>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#include "absl/memory/memory.h"
#include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "api/audio_codecs/builtin_audio_encoder_factory.h"
#include "api/task_queue/default_task_queue_factory.h"
#include "api/voip/voip_codec.h"
#include "api/voip/voip_engine_factory.h"
#include "api/voip/voip_network.h"
#include "examples/androidvoip/generated_jni/VoipClient_jni.h"
#include "rtc_base/logging.h"
#include "rtc_base/network.h"
#include "rtc_base/socket_server.h"
#include "sdk/android/native_api/audio_device_module/audio_device_android.h"
#include "sdk/android/native_api/jni/java_types.h"
#include "sdk/android/native_api/jni/jvm.h"
#include "sdk/android/native_api/jni/scoped_java_ref.h"

namespace {

#define RUN_ON_VOIP_THREAD(method, ...)                              \
  if (!voip_thread_->IsCurrent()) {                                  \
    voip_thread_->PostTask(                                          \
        std::bind(&AndroidVoipClient::method, this, ##__VA_ARGS__)); \
    return;                                                          \
  }                                                                  \
  RTC_DCHECK_RUN_ON(voip_thread_.get());

// Connects a UDP socket to a public address and returns the local
// address associated with it. Since it binds to the "any" address
// internally, it returns the default local address on a multi-homed
// endpoint. Implementation copied from
// BasicNetworkManager::QueryDefaultLocalAddress.
rtc::IPAddress QueryDefaultLocalAddress(int family) {
  const char kPublicIPv4Host[] = "8.8.8.8";
  const char kPublicIPv6Host[] = "2001:4860:4860::8888";
  const int kPublicPort = 53;
  std::unique_ptr<rtc::Thread> thread = rtc::Thread::CreateWithSocketServer();

  RTC_DCHECK(thread->socketserver() != nullptr);
  RTC_DCHECK(family == AF_INET || family == AF_INET6);

  std::unique_ptr<rtc::Socket> socket(
      thread->socketserver()->CreateSocket(family, SOCK_DGRAM));
  if (!socket) {
    RTC_LOG_ERR(LS_ERROR) << "Socket creation failed";
    return rtc::IPAddress();
  }

  auto host = family == AF_INET ? kPublicIPv4Host : kPublicIPv6Host;
  if (socket->Connect(rtc::SocketAddress(host, kPublicPort)) < 0) {
    if (socket->GetError() != ENETUNREACH &&
        socket->GetError() != EHOSTUNREACH) {
      RTC_LOG(LS_INFO) << "Connect failed with " << socket->GetError();
    }
    return rtc::IPAddress();
  }
  return socket->GetLocalAddress().ipaddr();
}

// Assigned payload type for supported built-in codecs. PCMU, PCMA,
// and G722 have set payload types. Whereas opus, ISAC, and ILBC
// have dynamic payload types.
enum class PayloadType : int {
  kPcmu = 0,
  kPcma = 8,
  kG722 = 9,
  kOpus = 96,
  kIsac = 97,
  kIlbc = 98,
};

// Returns the payload type corresponding to codec_name. Only
// supports the built-in codecs.
int GetPayloadType(const std::string& codec_name) {
  RTC_DCHECK(codec_name == "PCMU" || codec_name == "PCMA" ||
             codec_name == "G722" || codec_name == "opus" ||
             codec_name == "ISAC" || codec_name == "ILBC");

  if (codec_name == "PCMU") {
    return static_cast<int>(PayloadType::kPcmu);
  } else if (codec_name == "PCMA") {
    return static_cast<int>(PayloadType::kPcma);
  } else if (codec_name == "G722") {
    return static_cast<int>(PayloadType::kG722);
  } else if (codec_name == "opus") {
    return static_cast<int>(PayloadType::kOpus);
  } else if (codec_name == "ISAC") {
    return static_cast<int>(PayloadType::kIsac);
  } else if (codec_name == "ILBC") {
    return static_cast<int>(PayloadType::kIlbc);
  }

  RTC_DCHECK_NOTREACHED();
  return -1;
}

}  // namespace

namespace webrtc_examples {

void AndroidVoipClient::Init(
    JNIEnv* env,
    const webrtc::JavaParamRef<jobject>& application_context) {
  webrtc::VoipEngineConfig config;
  config.encoder_factory = webrtc::CreateBuiltinAudioEncoderFactory();
  config.decoder_factory = webrtc::CreateBuiltinAudioDecoderFactory();
  config.task_queue_factory = webrtc::CreateDefaultTaskQueueFactory();
  config.audio_device_module =
      webrtc::CreateJavaAudioDeviceModule(env, application_context.obj());
  config.audio_processing = webrtc::AudioProcessingBuilder().Create();

  voip_thread_->Start();

  // Due to consistent thread requirement on
  // modules/audio_device/android/audio_device_template.h,
  // code is invoked in the context of voip_thread_.
  voip_thread_->BlockingCall([this, &config] {
    RTC_DCHECK_RUN_ON(voip_thread_.get());

    supported_codecs_ = config.encoder_factory->GetSupportedEncoders();
    env_ = webrtc::AttachCurrentThreadIfNeeded();
    voip_engine_ = webrtc::CreateVoipEngine(std::move(config));
  });
}

AndroidVoipClient::~AndroidVoipClient() {
  voip_thread_->BlockingCall([this] {
    RTC_DCHECK_RUN_ON(voip_thread_.get());

    JavaVM* jvm = nullptr;
    env_->GetJavaVM(&jvm);
    if (!jvm) {
      RTC_LOG(LS_ERROR) << "Failed to retrieve JVM";
      return;
    }
    jint res = jvm->DetachCurrentThread();
    if (res != JNI_OK) {
      RTC_LOG(LS_ERROR) << "DetachCurrentThread failed: " << res;
    }
  });

  voip_thread_->Stop();
}

AndroidVoipClient* AndroidVoipClient::Create(
    JNIEnv* env,
    const webrtc::JavaParamRef<jobject>& application_context,
    const webrtc::JavaParamRef<jobject>& j_voip_client) {
  // Using `new` to access a non-public constructor.
  auto voip_client =
      absl::WrapUnique(new AndroidVoipClient(env, j_voip_client));
  voip_client->Init(env, application_context);
  return voip_client.release();
}

void AndroidVoipClient::GetSupportedCodecs(JNIEnv* env) {
  RUN_ON_VOIP_THREAD(GetSupportedCodecs, env);

  std::vector<std::string> names;
  for (const webrtc::AudioCodecSpec& spec : supported_codecs_) {
    names.push_back(spec.format.name);
  }
  webrtc::ScopedJavaLocalRef<jstring> (*convert_function)(
      JNIEnv*, const std::string&) = &webrtc::NativeToJavaString;
  Java_VoipClient_onGetSupportedCodecsCompleted(
      env_, j_voip_client_,
      webrtc::NativeToJavaList(env_, names, convert_function));
}

void AndroidVoipClient::GetLocalIPAddress(JNIEnv* env) {
  RUN_ON_VOIP_THREAD(GetLocalIPAddress, env);

  std::string local_ip_address;
  rtc::IPAddress ipv4_address = QueryDefaultLocalAddress(AF_INET);
  if (!ipv4_address.IsNil()) {
    local_ip_address = ipv4_address.ToString();
  } else {
    rtc::IPAddress ipv6_address = QueryDefaultLocalAddress(AF_INET6);
    if (!ipv6_address.IsNil()) {
      local_ip_address = ipv6_address.ToString();
    }
  }
  Java_VoipClient_onGetLocalIPAddressCompleted(
      env_, j_voip_client_, webrtc::NativeToJavaString(env_, local_ip_address));
}

void AndroidVoipClient::SetEncoder(const std::string& encoder) {
  RTC_DCHECK_RUN_ON(voip_thread_.get());

  if (!channel_) {
    RTC_LOG(LS_ERROR) << "Channel has not been created";
    return;
  }
  for (const webrtc::AudioCodecSpec& codec : supported_codecs_) {
    if (codec.format.name == encoder) {
      webrtc::VoipResult result = voip_engine_->Codec().SetSendCodec(
          *channel_, GetPayloadType(codec.format.name), codec.format);
      RTC_CHECK(result == webrtc::VoipResult::kOk);
      return;
    }
  }
}

void AndroidVoipClient::SetEncoder(
    JNIEnv* env,
    const webrtc::JavaParamRef<jstring>& j_encoder_string) {
  const std::string& chosen_encoder =
      webrtc::JavaToNativeString(env, j_encoder_string);
  voip_thread_->PostTask(
      [this, chosen_encoder] { SetEncoder(chosen_encoder); });
}

void AndroidVoipClient::SetDecoders(const std::vector<std::string>& decoders) {
  RTC_DCHECK_RUN_ON(voip_thread_.get());

  if (!channel_) {
    RTC_LOG(LS_ERROR) << "Channel has not been created";
    return;
  }
  std::map<int, webrtc::SdpAudioFormat> decoder_specs;
  for (const webrtc::AudioCodecSpec& codec : supported_codecs_) {
    if (std::find(decoders.begin(), decoders.end(), codec.format.name) !=
        decoders.end()) {
      decoder_specs.insert({GetPayloadType(codec.format.name), codec.format});
    }
  }

  webrtc::VoipResult result =
      voip_engine_->Codec().SetReceiveCodecs(*channel_, decoder_specs);
  RTC_CHECK(result == webrtc::VoipResult::kOk);
}

void AndroidVoipClient::SetDecoders(
    JNIEnv* env,
    const webrtc::JavaParamRef<jobject>& j_decoder_strings) {
  const std::vector<std::string>& chosen_decoders =
      webrtc::JavaListToNativeVector<std::string, jstring>(
          env, j_decoder_strings, &webrtc::JavaToNativeString);
  voip_thread_->PostTask(
      [this, chosen_decoders] { SetDecoders(chosen_decoders); });
}

void AndroidVoipClient::SetLocalAddress(const std::string& ip_address,
                                        const int port_number) {
  RTC_DCHECK_RUN_ON(voip_thread_.get());

  rtp_local_address_ = rtc::SocketAddress(ip_address, port_number);
  rtcp_local_address_ = rtc::SocketAddress(ip_address, port_number + 1);
}

void AndroidVoipClient::SetLocalAddress(
    JNIEnv* env,
    const webrtc::JavaParamRef<jstring>& j_ip_address_string,
    jint j_port_number_int) {
  const std::string& ip_address =
      webrtc::JavaToNativeString(env, j_ip_address_string);
  voip_thread_->PostTask([this, ip_address, j_port_number_int] {
    SetLocalAddress(ip_address, j_port_number_int);
  });
}

void AndroidVoipClient::SetRemoteAddress(const std::string& ip_address,
                                         const int port_number) {
  RTC_DCHECK_RUN_ON(voip_thread_.get());

  rtp_remote_address_ = rtc::SocketAddress(ip_address, port_number);
  rtcp_remote_address_ = rtc::SocketAddress(ip_address, port_number + 1);
}

void AndroidVoipClient::SetRemoteAddress(
    JNIEnv* env,
    const webrtc::JavaParamRef<jstring>& j_ip_address_string,
    jint j_port_number_int) {
  const std::string& ip_address =
      webrtc::JavaToNativeString(env, j_ip_address_string);
  voip_thread_->PostTask([this, ip_address, j_port_number_int] {
    SetRemoteAddress(ip_address, j_port_number_int);
  });
}

void AndroidVoipClient::StartSession(JNIEnv* env) {
  RUN_ON_VOIP_THREAD(StartSession, env);

  // CreateChannel guarantees to return valid channel id.
  channel_ = voip_engine_->Base().CreateChannel(this, absl::nullopt);

  rtp_socket_.reset(rtc::AsyncUDPSocket::Create(voip_thread_->socketserver(),
                                                rtp_local_address_));
  if (!rtp_socket_) {
    RTC_LOG_ERR(LS_ERROR) << "Socket creation failed";
    Java_VoipClient_onStartSessionCompleted(env_, j_voip_client_,
                                            /*isSuccessful=*/false);
    return;
  }
  rtp_socket_->RegisterReceivedPacketCallback(
      [&](rtc::AsyncPacketSocket* socket, const rtc::ReceivedPacket& packet) {
        OnSignalReadRTPPacket(socket, packet);
      });

  rtcp_socket_.reset(rtc::AsyncUDPSocket::Create(voip_thread_->socketserver(),
                                                 rtcp_local_address_));
  if (!rtcp_socket_) {
    RTC_LOG_ERR(LS_ERROR) << "Socket creation failed";
    Java_VoipClient_onStartSessionCompleted(env_, j_voip_client_,
                                            /*isSuccessful=*/false);
    return;
  }
  rtcp_socket_->RegisterReceivedPacketCallback(
      [&](rtc::AsyncPacketSocket* socket, const rtc::ReceivedPacket& packet) {
        OnSignalReadRTCPPacket(socket, packet);
      });
  Java_VoipClient_onStartSessionCompleted(env_, j_voip_client_,
                                          /*isSuccessful=*/true);
}

void AndroidVoipClient::StopSession(JNIEnv* env) {
  RUN_ON_VOIP_THREAD(StopSession, env);

  if (!channel_) {
    RTC_LOG(LS_ERROR) << "Channel has not been created";
    Java_VoipClient_onStopSessionCompleted(env_, j_voip_client_,
                                           /*isSuccessful=*/false);
    return;
  }
  if (voip_engine_->Base().StopSend(*channel_) != webrtc::VoipResult::kOk ||
      voip_engine_->Base().StopPlayout(*channel_) != webrtc::VoipResult::kOk) {
    Java_VoipClient_onStopSessionCompleted(env_, j_voip_client_,
                                           /*isSuccessful=*/false);
    return;
  }

  rtp_socket_->Close();
  rtcp_socket_->Close();

  webrtc::VoipResult result = voip_engine_->Base().ReleaseChannel(*channel_);
  RTC_CHECK(result == webrtc::VoipResult::kOk);

  channel_ = absl::nullopt;
  Java_VoipClient_onStopSessionCompleted(env_, j_voip_client_,
                                         /*isSuccessful=*/true);
}

void AndroidVoipClient::StartSend(JNIEnv* env) {
  RUN_ON_VOIP_THREAD(StartSend, env);

  if (!channel_) {
    RTC_LOG(LS_ERROR) << "Channel has not been created";
    Java_VoipClient_onStartSendCompleted(env_, j_voip_client_,
                                         /*isSuccessful=*/false);
    return;
  }
  bool sending_started =
      (voip_engine_->Base().StartSend(*channel_) == webrtc::VoipResult::kOk);
  Java_VoipClient_onStartSendCompleted(env_, j_voip_client_, sending_started);
}

void AndroidVoipClient::StopSend(JNIEnv* env) {
  RUN_ON_VOIP_THREAD(StopSend, env);

  if (!channel_) {
    RTC_LOG(LS_ERROR) << "Channel has not been created";
    Java_VoipClient_onStopSendCompleted(env_, j_voip_client_,
                                        /*isSuccessful=*/false);
    return;
  }
  bool sending_stopped =
      (voip_engine_->Base().StopSend(*channel_) == webrtc::VoipResult::kOk);
  Java_VoipClient_onStopSendCompleted(env_, j_voip_client_, sending_stopped);
}

void AndroidVoipClient::StartPlayout(JNIEnv* env) {
  RUN_ON_VOIP_THREAD(StartPlayout, env);

  if (!channel_) {
    RTC_LOG(LS_ERROR) << "Channel has not been created";
    Java_VoipClient_onStartPlayoutCompleted(env_, j_voip_client_,
                                            /*isSuccessful=*/false);
    return;
  }
  bool playout_started =
      (voip_engine_->Base().StartPlayout(*channel_) == webrtc::VoipResult::kOk);
  Java_VoipClient_onStartPlayoutCompleted(env_, j_voip_client_,
                                          playout_started);
}

void AndroidVoipClient::StopPlayout(JNIEnv* env) {
  RUN_ON_VOIP_THREAD(StopPlayout, env);

  if (!channel_) {
    RTC_LOG(LS_ERROR) << "Channel has not been created";
    Java_VoipClient_onStopPlayoutCompleted(env_, j_voip_client_,
                                           /*isSuccessful=*/false);
    return;
  }
  bool playout_stopped =
      (voip_engine_->Base().StopPlayout(*channel_) == webrtc::VoipResult::kOk);
  Java_VoipClient_onStopPlayoutCompleted(env_, j_voip_client_, playout_stopped);
}

void AndroidVoipClient::Delete(JNIEnv* env) {
  delete this;
}

void AndroidVoipClient::SendRtpPacket(const std::vector<uint8_t>& packet_copy) {
  RTC_DCHECK_RUN_ON(voip_thread_.get());

  if (!rtp_socket_->SendTo(packet_copy.data(), packet_copy.size(),
                           rtp_remote_address_, rtc::PacketOptions())) {
    RTC_LOG(LS_ERROR) << "Failed to send RTP packet";
  }
}

bool AndroidVoipClient::SendRtp(rtc::ArrayView<const uint8_t> packet,
                                const webrtc::PacketOptions& options) {
  std::vector<uint8_t> packet_copy(packet.begin(), packet.end());
  voip_thread_->PostTask([this, packet_copy = std::move(packet_copy)] {
    SendRtpPacket(packet_copy);
  });
  return true;
}

void AndroidVoipClient::SendRtcpPacket(
    const std::vector<uint8_t>& packet_copy) {
  RTC_DCHECK_RUN_ON(voip_thread_.get());

  if (!rtcp_socket_->SendTo(packet_copy.data(), packet_copy.size(),
                            rtcp_remote_address_, rtc::PacketOptions())) {
    RTC_LOG(LS_ERROR) << "Failed to send RTCP packet";
  }
}

bool AndroidVoipClient::SendRtcp(rtc::ArrayView<const uint8_t> packet) {
  std::vector<uint8_t> packet_copy(packet.begin(), packet.end());
  voip_thread_->PostTask([this, packet_copy = std::move(packet_copy)] {
    SendRtcpPacket(packet_copy);
  });
  return true;
}

void AndroidVoipClient::ReadRTPPacket(const std::vector<uint8_t>& packet_copy) {
  RTC_DCHECK_RUN_ON(voip_thread_.get());

  if (!channel_) {
    RTC_LOG(LS_ERROR) << "Channel has not been created";
    return;
  }
  webrtc::VoipResult result = voip_engine_->Network().ReceivedRTPPacket(
      *channel_,
      rtc::ArrayView<const uint8_t>(packet_copy.data(), packet_copy.size()));
  RTC_CHECK(result == webrtc::VoipResult::kOk);
}

void AndroidVoipClient::OnSignalReadRTPPacket(
    rtc::AsyncPacketSocket* socket,
    const rtc::ReceivedPacket& packet) {
  std::vector<uint8_t> packet_copy(packet.payload().begin(),
                                   packet.payload().end());
  voip_thread_->PostTask([this, packet_copy = std::move(packet_copy)] {
    ReadRTPPacket(packet_copy);
  });
}

void AndroidVoipClient::ReadRTCPPacket(
    const std::vector<uint8_t>& packet_copy) {
  RTC_DCHECK_RUN_ON(voip_thread_.get());

  if (!channel_) {
    RTC_LOG(LS_ERROR) << "Channel has not been created";
    return;
  }
  webrtc::VoipResult result = voip_engine_->Network().ReceivedRTCPPacket(
      *channel_,
      rtc::ArrayView<const uint8_t>(packet_copy.data(), packet_copy.size()));
  RTC_CHECK(result == webrtc::VoipResult::kOk);
}

void AndroidVoipClient::OnSignalReadRTCPPacket(
    rtc::AsyncPacketSocket* socket,
    const rtc::ReceivedPacket& packet) {
  std::vector<uint8_t> packet_copy(packet.payload().begin(),
                                   packet.payload().end());
  voip_thread_->PostTask([this, packet_copy = std::move(packet_copy)] {
    ReadRTCPPacket(packet_copy);
  });
}

static jlong JNI_VoipClient_CreateClient(
    JNIEnv* env,
    const webrtc::JavaParamRef<jobject>& application_context,
    const webrtc::JavaParamRef<jobject>& j_voip_client) {
  return webrtc::NativeToJavaPointer(
      AndroidVoipClient::Create(env, application_context, j_voip_client));
}

}  // namespace webrtc_examples
