#!/bin/sh

#
# Copyright 2019-2021 Signal Messenger, LLC
# SPDX-License-Identifier: AGPL-3.0-only
#

# Be sure of the following pre-requisites in your environment (MacOS & Xcode):
#
# $ xcode-select --install
# $ rustup target add aarch64-apple-ios x86_64-apple-ios
# $ cargo install cargo-lipo
# $ cargo install cbindgen
#
# The goal of this script is to do the following:
# 1) Build WebRTC using existing (but modified) scripts for iOS,
#    resulting in WebRTC.framework.
# 2) Build the RingRTC Rust library and associated header file.
#    This is libringrtc.a and ringrtc.h.
#
# The Signal-iOS client project should include both the libringrtc
# and WebRTC.framework directories, copied from out/ to the
# the ThirdParty/WebRTC/Build directory. The contents of the
# SignalRingRTC project will live in the ThirdParty/RingRTC directory.
#

set -e

BIN_DIR="$(realpath -e $(dirname $0))"
. "${BIN_DIR}/env.sh"

usage()
{
    echo 'usage: build-ios [-d|-c] [-w, -r]
    where:
        -d is for debug builds (default is release)
        -c (or --clean) cleans the build artifacts
        -w builds WebRTC.framework only
        -r builds libringrtc.a/h only
        
        Only one w or r option should be used at a time.
        If no options are specified, everything is built with
        release configuration.'
}

clean()
{
  # Remove all possible artifact directories.
  rm -r -f ${OUTPUT_DIR}/debug
  rm -r -f ${OUTPUT_DIR}/release
  rm -r -f ${OUTPUT_DIR}/WebRTC.framework
  rm -r -f ${OUTPUT_DIR}/WebRTC.framework.dSYM
  rm -r -f ${RINGRTC_SRC_DIR}/rust/target/release
  rm -r -f ${RINGRTC_SRC_DIR}/rust/target/debug
  rm -r -f ${RINGRTC_SRC_DIR}/rust/target/universal
  rm -r -f ${RINGRTC_SRC_DIR}/rust/target/x86_64-apple-ios
  rm -r -f ${RINGRTC_SRC_DIR}/rust/target/aarch64-apple-ios
  rm -r -f ${OUTPUT_DIR}/libringrtc
  rm -r -f ${OUTPUT_DIR}/build
}

# The default build (out of git) is release. However, we don't keep
# both types at the same time. It is either debug OR release.

BUILD_WHAT=all
BUILD_TYPE=release

while [ "$1" != "" ]; do
    case $1 in
        -d | --debug )
            BUILD_TYPE=debug
            ;;
        -w )
            BUILD_WHAT=webrtc
            ;;
        -r )
            BUILD_WHAT=ringrtc
            ;;
        -c | --clean )
            clean
            exit
            ;;
        -h | --help )
            usage
            exit
            ;;
        * )
            usage
            exit 1
    esac
    shift
done

# The WebRTC part of the build resulting in WebRTC.framework.
if [ "${BUILD_WHAT}" = "all" ] || [ "${BUILD_WHAT}" = "webrtc" ]
then
  echo "Building the WebRTC.framework in ${OUTPUT_DIR}/${BUILD_TYPE}..."

  (cd ${WEBRTC_SRC_DIR} && ./tools_webrtc/ios/build_ios_libs.py -o ${OUTPUT_DIR}/${BUILD_TYPE} --build_config ${BUILD_TYPE} --arch {arm64,x64} --extra-gn-args rtc_enable_sctp=false)

  echo "Copying to ${OUTPUT_DIR}"

  # Copy WebRTC.framework up.
  cp -r -f ${OUTPUT_DIR}/${BUILD_TYPE}/WebRTC.framework ${OUTPUT_DIR}

  # Copy WebRTC.dSYM up for local debugging.
  cp -r -f ${OUTPUT_DIR}/${BUILD_TYPE}/WebRTC.dSYM ${OUTPUT_DIR}/WebRTC.framework.dSYM

  "${BIN_DIR}/print_build_env.py" \
      --webrtc-version="${WEBRTC_VERSION}" \
      --ringrtc-version="${PROJECT_VERSION}" > ${OUTPUT_DIR}/WebRTC.framework/build_env.txt
fi

# The RingRTC part of the build resulting in a library built from Rust.
if [ "${BUILD_WHAT}" = "all" ] || [ "${BUILD_WHAT}" = "ringrtc" ]
then
  # @todo It would be nice if cargo lipo could output to a different
  # directory for an out-of-source build...

  echo "Creating universal binary in ${OUTPUT_DIR}/libringrtc..."

  (
  cd ${RINGRTC_SRC_DIR}/rust

  if [ "${BUILD_TYPE}" = "debug" ]
  then
    OUTPUT_DIR="${OUTPUT_DIR}" cargo lipo --targets aarch64-apple-ios,x86_64-apple-ios
  else
    OUTPUT_DIR="${OUTPUT_DIR}" cargo lipo --release --targets aarch64-apple-ios,x86_64-apple-ios
  fi

  mkdir -p ${OUTPUT_DIR}/libringrtc
  cp -f ${RINGRTC_SRC_DIR}/rust/target/universal/${BUILD_TYPE}/libringrtc.a ${OUTPUT_DIR}/libringrtc/libringrtc.a

  # Create the modulemap:
  echo 'framework module SignalRingRTC {
      umbrella header "SignalRingRTC.h"
      export *
      module * { export * }
      explicit module SignalRingRTC_Private {
          header "ringrtc.h"
          link "ringrtc"
          export *
      }
  }' >${OUTPUT_DIR}/libringrtc/RingRTC.modulemap

  # Create the test podspec for WebRTC:
  echo 'Pod::Spec.new do |s|
    s.name     = "WebRTCForTesting"
    s.version  = "0.0.1"
    s.summary  = "Intended only for testing SignalRingRTC within this repository"
    s.license  = "BSD"
    s.homepage = "https://github.com/signalapp/webrtc"
    s.source   = { git: "https://github.com/signalapp/webrtc.git" }
    s.author   = { "iOS Team": "ios@signal.org" }

    s.platform = :ios, "11.0"
    s.vendored_frameworks = "WebRTC.framework"
  end' >${OUTPUT_DIR}/WebRTCForTesting.podspec

  echo "Creating header file in ${OUTPUT_DIR}/libringrtc..."
  cbindgen ${RINGRTC_SRC_DIR}/rust/src/lib.rs --config ${RINGRTC_SRC_DIR}/rust/cbindgen.toml -o ${OUTPUT_DIR}/libringrtc/ringrtc.h
  )
fi

echo "Done with the iOS build for RingRTC!"
