/*
 * libjingle
 * Copyright 2014, 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.
 */

package org.appspot.apprtc;

import org.appspot.apprtc.AppRTCClient.SignalingParameters;
import org.appspot.apprtc.util.LooperExecutor;

import android.content.Context;
import android.opengl.EGLContext;
import android.util.Log;

import org.webrtc.DataChannel;
import org.webrtc.IceCandidate;
import org.webrtc.MediaConstraints;
import org.webrtc.MediaConstraints.KeyValuePair;
import org.webrtc.MediaStream;
import org.webrtc.MediaStreamTrack;
import org.webrtc.PeerConnection;
import org.webrtc.PeerConnection.IceConnectionState;
import org.webrtc.PeerConnectionFactory;
import org.webrtc.SdpObserver;
import org.webrtc.SessionDescription;
import org.webrtc.StatsObserver;
import org.webrtc.VideoCapturer;
import org.webrtc.VideoRenderer;
import org.webrtc.VideoSource;
import org.webrtc.VideoTrack;

import java.util.LinkedList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Peer connection client implementation.
 *
 * <p>All public methods are routed to local looper thread.
 * All PeerConnectionEvents callbacks are invoked from the same looper thread.
 */
public class PeerConnectionClient {
  private static final String TAG = "PCRTCClient";
  private static final boolean PREFER_ISAC = false;
  public static final String VIDEO_TRACK_ID = "ARDAMSv0";
  public static final String AUDIO_TRACK_ID = "ARDAMSa0";

  private final LooperExecutor executor;
  private PeerConnectionFactory factory = null;
  private PeerConnection pc = null;
  private VideoSource videoSource;
  private boolean videoSourceStopped = false;
  private boolean isError = false;
  private final PCObserver pcObserver = new PCObserver();
  private final SDPObserver sdpObserver = new SDPObserver();
  private VideoRenderer.Callbacks localRender;
  private VideoRenderer.Callbacks remoteRender;
  private SignalingParameters signalingParameters;
  // Queued remote ICE candidates are consumed only after both local and
  // remote descriptions are set. Similarly local ICE candidates are sent to
  // remote peer after both local and remote description are set.
  private LinkedList<IceCandidate> queuedRemoteCandidates = null;
  private MediaConstraints sdpMediaConstraints;
  private PeerConnectionEvents events;
  private int startBitrate;
  private boolean isInitiator;
  private boolean useFrontFacingCamera = true;
  private SessionDescription localSdp = null; // either offer or answer SDP
  private MediaStream mediaStream = null;

  /**
   * SDP/ICE ready callbacks.
   */
  public static interface PeerConnectionEvents {
    /**
     * Callback fired once local SDP is created and set.
     */
    public void onLocalDescription(final SessionDescription sdp);

    /**
     * Callback fired once local Ice candidate is generated.
     */
    public void onIceCandidate(final IceCandidate candidate);

    /**
     * Callback fired once connection is established (IceConnectionState is
     * CONNECTED).
     */
    public void onIceConnected();

    /**
     * Callback fired once connection is closed (IceConnectionState is
     * DISCONNECTED).
     */
    public void onIceDisconnected();

    /**
     * Callback fired once peer connection is closed.
     */
    public void onPeerConnectionClosed();

    /**
     * Callback fired once peer connection error happened.
     */
    public void onPeerConnectionError(final String description);

  }

  public PeerConnectionClient() {
    executor = new LooperExecutor();
  }

  public void createPeerConnectionFactory(
      final Context context,
      final boolean vp8HwAcceleration,
      final EGLContext renderEGLContext,
      final PeerConnectionEvents events) {
    this.events = events;
    executor.requestStart();
    executor.execute(new Runnable() {
      @Override
      public void run() {
        createPeerConnectionFactoryInternal(
            context, vp8HwAcceleration, renderEGLContext);
      }
    });
  }

  public void createPeerConnection(
      final VideoRenderer.Callbacks localRender,
      final VideoRenderer.Callbacks remoteRender,
      final SignalingParameters signalingParameters,
      final int startBitrate) {
    this.localRender = localRender;
    this.remoteRender = remoteRender;
    this.signalingParameters = signalingParameters;
    this.startBitrate = startBitrate;
    executor.execute(new Runnable() {
      @Override
      public void run() {
        createPeerConnectionInternal();
      }
    });
  }

  public void close() {
    executor.execute(new Runnable() {
      @Override
      public void run() {
        closeInternal();
      }
    });
    executor.requestStop();
  }

  private void createPeerConnectionFactoryInternal(
      Context context,
      boolean vp8HwAcceleration,
      EGLContext renderEGLContext) {
    Log.d(TAG, "Create peer connection factory with EGLContext "
      + renderEGLContext);
    isError = false;
    if (!PeerConnectionFactory.initializeAndroidGlobals(
        context, true, true, vp8HwAcceleration, renderEGLContext)) {
      events.onPeerConnectionError("Failed to initializeAndroidGlobals");
    }
    factory = new PeerConnectionFactory();
    Log.d(TAG, "Peer connection factory created.");
  }

  private void createPeerConnectionInternal() {
    if (factory == null || isError) {
      Log.e(TAG, "Peerconnection factory is not created");
      return;
    }
    Log.d(TAG, "Create peer connection.");
    isInitiator = signalingParameters.initiator;
    queuedRemoteCandidates = new LinkedList<IceCandidate>();

    sdpMediaConstraints = new MediaConstraints();
    sdpMediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair(
        "OfferToReceiveAudio", "true"));
    sdpMediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair(
        "OfferToReceiveVideo", "true"));

    MediaConstraints pcConstraints = signalingParameters.pcConstraints;
    pcConstraints.optional.add(
        new MediaConstraints.KeyValuePair("RtpDataChannels", "true"));
    pc = factory.createPeerConnection(signalingParameters.iceServers,
        pcConstraints, pcObserver);
    isInitiator = false;

    // Uncomment to get ALL WebRTC tracing and SENSITIVE libjingle logging.
    // NOTE: this _must_ happen while |factory| is alive!
    // Logging.enableTracing(
    //     "logcat:",
    //     EnumSet.of(Logging.TraceLevel.TRACE_ALL),
    //     Logging.Severity.LS_SENSITIVE);

    mediaStream = factory.createLocalMediaStream("ARDAMS");
    if (signalingParameters.videoConstraints != null) {
      mediaStream.addTrack(createVideoTrack(useFrontFacingCamera));
    }

    if (signalingParameters.audioConstraints != null) {
      mediaStream.addTrack(factory.createAudioTrack(
          AUDIO_TRACK_ID,
          factory.createAudioSource(signalingParameters.audioConstraints)));
    }
    pc.addStream(mediaStream);
    Log.d(TAG, "Peer connection created.");
  }

  private void closeInternal() {
    Log.d(TAG, "Closing peer connection.");
    if (pc != null) {
      pc.dispose();
      pc = null;
    }
    if (videoSource != null) {
      videoSource.dispose();
      videoSource = null;
    }
    Log.d(TAG, "Closing peer connection factory.");
    if (factory != null) {
      factory.dispose();
      factory = null;
    }
    Log.d(TAG, "Closing peer connection done.");
    events.onPeerConnectionClosed();
  }

  public boolean isHDVideo() {
    if (signalingParameters.videoConstraints == null) {
      return false;
    }
    int minWidth = 0;
    int minHeight = 0;
    for (KeyValuePair keyValuePair :
        signalingParameters.videoConstraints.mandatory) {
      if (keyValuePair.getKey().equals("minWidth")) {
        try {
          minWidth = Integer.parseInt(keyValuePair.getValue());
        } catch (NumberFormatException e) {
          Log.e(TAG, "Can not parse video width from video constraints");
        }
      } else if (keyValuePair.getKey().equals("minHeight")) {
        try {
          minHeight = Integer.parseInt(keyValuePair.getValue());
        } catch (NumberFormatException e) {
          Log.e(TAG, "Can not parse video height from video constraints");
        }
      }
    }
    if (minWidth * minHeight >= 1280 * 720) {
      return true;
    } else {
      return false;
    }
  }

  public boolean getStats(StatsObserver observer, MediaStreamTrack track) {
    if (pc != null && !isError) {
      return pc.getStats(observer, track);
    } else {
      return false;
    }
  }

  public void createOffer() {
    executor.execute(new Runnable() {
      @Override
      public void run() {
        if (pc != null && !isError) {
          Log.d(TAG, "PC Create OFFER");
          isInitiator = true;
          pc.createOffer(sdpObserver, sdpMediaConstraints);
        }
      }
    });
  }

  public void createAnswer() {
    executor.execute(new Runnable() {
      @Override
      public void run() {
        if (pc != null && !isError) {
          Log.d(TAG, "PC create ANSWER");
          isInitiator = false;
          pc.createAnswer(sdpObserver, sdpMediaConstraints);
        }
      }
    });
  }

  public void addRemoteIceCandidate(final IceCandidate candidate) {
    executor.execute(new Runnable() {
      @Override
      public void run() {
        if (pc != null && !isError) {
          if (queuedRemoteCandidates != null) {
            queuedRemoteCandidates.add(candidate);
          } else {
            pc.addIceCandidate(candidate);
          }
        }
      }
    });
  }

  public void setRemoteDescription(final SessionDescription sdp) {
    executor.execute(new Runnable() {
      @Override
      public void run() {
        if (pc == null || isError) {
          return;
        }
        String sdpDescription = sdp.description;
        if (PREFER_ISAC) {
          sdpDescription = preferISAC(sdpDescription);
        }
        if (startBitrate > 0) {
          sdpDescription = setStartBitrate(sdpDescription, startBitrate);
        }
        Log.d(TAG, "Set remote SDP.");
        SessionDescription sdpRemote = new SessionDescription(
            sdp.type, sdpDescription);
        pc.setRemoteDescription(sdpObserver, sdpRemote);
      }
    });
  }

  public void stopVideoSource() {
    executor.execute(new Runnable() {
      @Override
      public void run() {
        if (videoSource != null && !videoSourceStopped) {
          Log.d(TAG, "Stop video source.");
          videoSource.stop();
          videoSourceStopped = true;
        }
      }
    });
  }

  public void startVideoSource() {
    executor.execute(new Runnable() {
      @Override
      public void run() {
        if (videoSource != null && videoSourceStopped) {
          Log.d(TAG, "Restart video source.");
          videoSource.restart();
          videoSourceStopped = false;
        }
      }
    });
  }

  private void reportError(final String errorMessage) {
    Log.e(TAG, "Peerconnection error: " + errorMessage);
    executor.execute(new Runnable() {
      @Override
      public void run() {
        if (!isError) {
          events.onPeerConnectionError(errorMessage);
          isError = true;
        }
      }
    });
  }

  // Cycle through likely device names for the camera and return the first
  // capturer that works, or crash if none do.
  private VideoCapturer getVideoCapturer(boolean useFrontFacing) {
    String[] cameraFacing = { "front", "back" };
    if (!useFrontFacing) {
      cameraFacing[0] = "back";
      cameraFacing[1] = "front";
    }
    for (String facing : cameraFacing) {
      int[] cameraIndex = { 0, 1 };
      int[] cameraOrientation = { 0, 90, 180, 270 };
      for (int index : cameraIndex) {
        for (int orientation : cameraOrientation) {
          String name = "Camera " + index + ", Facing " + facing
              + ", Orientation " + orientation;
          VideoCapturer capturer = VideoCapturer.create(name);
          if (capturer != null) {
            Log.d(TAG, "Using camera: " + name);
            return capturer;
          }
        }
      }
    }
    reportError("Failed to open capturer");
    return null;
  }

  private VideoTrack createVideoTrack(boolean frontFacing) {
    VideoCapturer capturer = getVideoCapturer(frontFacing);
    if (videoSource != null) {
      videoSource.stop();
      videoSource.dispose();
    }

    videoSource = factory.createVideoSource(
        capturer, signalingParameters.videoConstraints);
    String trackExtension = frontFacing ? "frontFacing" : "backFacing";
    VideoTrack videoTrack =
        factory.createVideoTrack(VIDEO_TRACK_ID + trackExtension, videoSource);
    videoTrack.addRenderer(new VideoRenderer(localRender));
    return videoTrack;
  }

  private static String setStartBitrate(
      String sdpDescription, int bitrateKbps) {
    String[] lines = sdpDescription.split("\r\n");
    int lineIndex = -1;
    String vp8RtpMap = null;
    Pattern vp8Pattern =
        Pattern.compile("^a=rtpmap:(\\d+) VP8/90000[\r]?$");
    for (int i = 0; i < lines.length; i++) {
      Matcher vp8Matcher = vp8Pattern.matcher(lines[i]);
      if (vp8Matcher.matches()) {
        vp8RtpMap = vp8Matcher.group(1);
        lineIndex = i;
        break;
      }
    }
    if (vp8RtpMap == null) {
      Log.e(TAG, "No rtpmap for VP8 codec");
      return sdpDescription;
    }
    Log.d(TAG, "Found rtpmap " + vp8RtpMap + " at " + lines[lineIndex]);
    StringBuilder newSdpDescription = new StringBuilder();
    for (int i = 0; i < lines.length; i++) {
      newSdpDescription.append(lines[i]).append("\r\n");
      if (i == lineIndex) {
        String bitrateSet = "a=fmtp:" + vp8RtpMap
            + " x-google-start-bitrate=" + bitrateKbps;
        Log.d(TAG, "Add remote SDP line: " + bitrateSet);
        newSdpDescription.append(bitrateSet).append("\r\n");
      }
    }
    return newSdpDescription.toString();
  }

  // Mangle SDP to prefer ISAC/16000 over any other audio codec.
  private static String preferISAC(String sdpDescription) {
    String[] lines = sdpDescription.split("\r\n");
    int mLineIndex = -1;
    String isac16kRtpMap = null;
    Pattern isac16kPattern =
        Pattern.compile("^a=rtpmap:(\\d+) ISAC/16000[\r]?$");
    for (int i = 0;
         (i < lines.length) && (mLineIndex == -1 || isac16kRtpMap == null);
         ++i) {
      if (lines[i].startsWith("m=audio ")) {
        mLineIndex = i;
        continue;
      }
      Matcher isac16kMatcher = isac16kPattern.matcher(lines[i]);
      if (isac16kMatcher.matches()) {
        isac16kRtpMap = isac16kMatcher.group(1);
        continue;
      }
    }
    if (mLineIndex == -1) {
      Log.d(TAG, "No m=audio line, so can't prefer iSAC");
      return sdpDescription;
    }
    if (isac16kRtpMap == null) {
      Log.d(TAG, "No ISAC/16000 line, so can't prefer iSAC");
      return sdpDescription;
    }
    String[] origMLineParts = lines[mLineIndex].split(" ");
    StringBuilder newMLine = new StringBuilder();
    int origPartIndex = 0;
    // Format is: m=<media> <port> <proto> <fmt> ...
    newMLine.append(origMLineParts[origPartIndex++]).append(" ");
    newMLine.append(origMLineParts[origPartIndex++]).append(" ");
    newMLine.append(origMLineParts[origPartIndex++]).append(" ");
    newMLine.append(isac16kRtpMap);
    for (; origPartIndex < origMLineParts.length; ++origPartIndex) {
      if (!origMLineParts[origPartIndex].equals(isac16kRtpMap)) {
        newMLine.append(" ").append(origMLineParts[origPartIndex]);
      }
    }
    lines[mLineIndex] = newMLine.toString();
    StringBuilder newSdpDescription = new StringBuilder();
    for (String line : lines) {
      newSdpDescription.append(line).append("\r\n");
    }
    return newSdpDescription.toString();
  }

  private void drainCandidates() {
    if (queuedRemoteCandidates != null) {
      Log.d(TAG, "Add " + queuedRemoteCandidates.size() + " remote candidates");
      for (IceCandidate candidate : queuedRemoteCandidates) {
        pc.addIceCandidate(candidate);
      }
      queuedRemoteCandidates = null;
    }
  }

  private void switchCameraInternal() {
    if (signalingParameters.videoConstraints == null) {
      return;  // No video is sent.
    }
    if (pc.signalingState() != PeerConnection.SignalingState.STABLE) {
      Log.e(TAG, "Switching camera during negotiation is not handled.");
      return;
    }

    Log.d(TAG, "Switch camera");
    pc.removeStream(mediaStream);
    VideoTrack currentTrack = mediaStream.videoTracks.get(0);
    mediaStream.removeTrack(currentTrack);

    String trackId = currentTrack.id();
    // On Android, there can only be one camera open at the time and we
    // need to release our implicit references to the videoSource before the
    // PeerConnectionFactory is released. Since createVideoTrack creates a new
    // videoSource and frees the old one, we need to release the track here.
    currentTrack.dispose();

    useFrontFacingCamera = !useFrontFacingCamera;
    VideoTrack newTrack = createVideoTrack(useFrontFacingCamera);
    mediaStream.addTrack(newTrack);
    pc.addStream(mediaStream);

    SessionDescription remoteDesc = pc.getRemoteDescription();
    if (localSdp == null || remoteDesc == null) {
      Log.d(TAG, "Switching camera before the negotiation started.");
      return;
    }

    localSdp = new SessionDescription(localSdp.type,
        localSdp.description.replaceAll(trackId, newTrack.id()));

    if (isInitiator) {
      pc.setLocalDescription(new SwitchCameraSdbObserver(), localSdp);
      pc.setRemoteDescription(new SwitchCameraSdbObserver(), remoteDesc);
    } else {
      pc.setRemoteDescription(new SwitchCameraSdbObserver(), remoteDesc);
      pc.setLocalDescription(new SwitchCameraSdbObserver(), localSdp);
    }
    Log.d(TAG, "Switch camera done");
  }

  public void switchCamera() {
    executor.execute(new Runnable() {
      @Override
      public void run() {
        if (pc != null && !isError) {
          switchCameraInternal();
        }
      }
    });
  }

  // Implementation detail: observe ICE & stream changes and react accordingly.
  private class PCObserver implements PeerConnection.Observer {
    @Override
    public void onIceCandidate(final IceCandidate candidate){
      executor.execute(new Runnable() {
        @Override
        public void run() {
          events.onIceCandidate(candidate);
        }
      });
    }

    @Override
    public void onSignalingChange(
        PeerConnection.SignalingState newState) {
      Log.d(TAG, "SignalingState: " + newState);
    }

    @Override
    public void onIceConnectionChange(
        final PeerConnection.IceConnectionState newState) {
      executor.execute(new Runnable() {
        @Override
        public void run() {
          Log.d(TAG, "IceConnectionState: " + newState);
          if (newState == IceConnectionState.CONNECTED) {
            events.onIceConnected();
          } else if (newState == IceConnectionState.DISCONNECTED) {
            events.onIceDisconnected();
          } else if (newState == IceConnectionState.FAILED) {
            reportError("ICE connection failed.");
          }
        }
      });
    }

    @Override
    public void onIceGatheringChange(
      PeerConnection.IceGatheringState newState) {
      Log.d(TAG, "IceGatheringState: " + newState);
    }

    @Override
    public void onAddStream(final MediaStream stream){
      executor.execute(new Runnable() {
        @Override
        public void run() {
          if (pc == null || isError) {
            return;
          }
          if (stream.audioTracks.size() > 1 || stream.videoTracks.size() > 1) {
            reportError("Weird-looking stream: " + stream);
            return;
          }
          if (stream.videoTracks.size() == 1) {
            stream.videoTracks.get(0).addRenderer(
                new VideoRenderer(remoteRender));
          }
        }
      });
    }

    @Override
    public void onRemoveStream(final MediaStream stream){
      executor.execute(new Runnable() {
        @Override
        public void run() {
          if (pc == null || isError) {
            return;
          }
          stream.videoTracks.get(0).dispose();
        }
      });
    }

    @Override
    public void onDataChannel(final DataChannel dc) {
      reportError("AppRTC doesn't use data channels, but got: " + dc.label()
          + " anyway!");
    }

    @Override
    public void onRenegotiationNeeded() {
      // No need to do anything; AppRTC follows a pre-agreed-upon
      // signaling/negotiation protocol.
    }
  }

  // Implementation detail: handle offer creation/signaling and answer setting,
  // as well as adding remote ICE candidates once the answer SDP is set.
  private class SDPObserver implements SdpObserver {
    @Override
    public void onCreateSuccess(final SessionDescription origSdp) {
      if (localSdp != null) {
        reportError("Multiple SDP create.");
        return;
      }
      String sdpDescription = origSdp.description;
      if (PREFER_ISAC) {
        sdpDescription = preferISAC(sdpDescription);
      }
      final SessionDescription sdp = new SessionDescription(
          origSdp.type, sdpDescription);
      localSdp = sdp;
      executor.execute(new Runnable() {
        @Override
        public void run() {
          if (pc != null && !isError) {
            Log.d(TAG, "Set local SDP from " + sdp.type);
            pc.setLocalDescription(sdpObserver, sdp);
          }
        }
      });
    }

    @Override
    public void onSetSuccess() {
      executor.execute(new Runnable() {
        @Override
        public void run() {
          if (pc == null || isError) {
            return;
          }
          if (isInitiator) {
            // For offering peer connection we first create offer and set
            // local SDP, then after receiving answer set remote SDP.
            if (pc.getRemoteDescription() == null) {
              // We've just set our local SDP so time to send it.
              Log.d(TAG, "Local SDP set succesfully");
              events.onLocalDescription(localSdp);
            } else {
              // We've just set remote description, so drain remote
              // and send local ICE candidates.
              Log.d(TAG, "Remote SDP set succesfully");
              drainCandidates();
            }
          } else {
            // For answering peer connection we set remote SDP and then
            // create answer and set local SDP.
            if (pc.getLocalDescription() != null) {
              // We've just set our local SDP so time to send it, drain
              // remote and send local ICE candidates.
              Log.d(TAG, "Local SDP set succesfully");
              events.onLocalDescription(localSdp);
              drainCandidates();
            } else {
              // We've just set remote SDP - do nothing for now -
              // answer will be created soon.
              Log.d(TAG, "Remote SDP set succesfully");
            }
          }
        }
      });
    }

    @Override
    public void onCreateFailure(final String error) {
      reportError("createSDP error: " + error);
    }

    @Override
    public void onSetFailure(final String error) {
      reportError("setSDP error: " + error);
    }
  }

  private class SwitchCameraSdbObserver implements SdpObserver {
    @Override
    public void onCreateSuccess(SessionDescription sdp) {
    }

    @Override
    public void onSetSuccess() {
      Log.d(TAG, "Camera switch SDP set succesfully");
    }

    @Override
    public void onCreateFailure(final String error) {
    }

    @Override
    public void onSetFailure(final String error) {
      reportError("setSDP error while switching camera: " + error);
    }
  }
}
