/*
       Licensed to the Apache Software Foundation (ASF) under one
       or more contributor license agreements.  See the NOTICE file
       distributed with this work for additional information
       regarding copyright ownership.  The ASF licenses this file
       to you under the Apache License, Version 2.0 (the
       "License"); you may not use this file except in compliance
       with the License.  You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

       Unless required by applicable law or agreed to in writing,
       software distributed under the License is distributed on an
       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
       KIND, either express or implied.  See the License for the
       specific language governing permissions and limitations
       under the License.
*/
package org.apache.cordova.media;

import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.media.MediaRecorder;
import android.os.Environment;
import android.os.Build;

import org.apache.cordova.LOG;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.util.LinkedList;

/**
 * This class implements the audio playback and recording capabilities used by Cordova.
 * It is called by the AudioHandler Cordova class.
 * Only one file can be played or recorded per class instance.
 *
 * Local audio files must reside in one of two places:
 *      android_asset:      file name must start with /android_asset/sound.mp3
 *      sdcard:             file name is just sound.mp3
 */
public class AudioPlayer implements OnCompletionListener, OnPreparedListener, OnErrorListener {

    // AudioPlayer modes
    public enum MODE { NONE, PLAY, RECORD };

    // AudioPlayer states
    public enum STATE { MEDIA_NONE,
                        MEDIA_STARTING,
                        MEDIA_RUNNING,
                        MEDIA_PAUSED,
                        MEDIA_STOPPED,
                        MEDIA_LOADING
                      };

    private static final String LOG_TAG = "AudioPlayer";

    // AudioPlayer message ids
    private static int MEDIA_STATE = 1;
    private static int MEDIA_DURATION = 2;
    private static int MEDIA_POSITION = 3;
    private static int MEDIA_ERROR = 9;

    // Media error codes
    private static int MEDIA_ERR_NONE_ACTIVE    = 0;
    private static int MEDIA_ERR_ABORTED        = 1;
//    private static int MEDIA_ERR_NETWORK        = 2;
//    private static int MEDIA_ERR_DECODE         = 3;
//    private static int MEDIA_ERR_NONE_SUPPORTED = 4;

    private AudioHandler handler;           // The AudioHandler object
    private Context context;                // The Application Context object
    private String id;                      // The id of this player (used to identify Media object in JavaScript)
    private MODE mode = MODE.NONE;          // Playback or Recording mode
    private STATE state = STATE.MEDIA_NONE; // State of recording or playback

    private String audioFile = null;        // File name to play or record to
    private float duration = -1;            // Duration of audio

    private MediaRecorder recorder = null;  // Audio recording object
    private LinkedList<String> tempFiles = null; // Temporary recording file name
    private String tempFile = null;

    private MediaPlayer player = null;      // Audio player object
    private boolean prepareOnly = true;     // playback after file prepare flag
    private int seekOnPrepared = 0;     // seek to this location once media is prepared
    private float setRateOnPrepared = -1;

    /**
     * Constructor.
     *
     * @param handler           The audio handler object
     * @param id                The id of this audio player
     */
    public AudioPlayer(AudioHandler handler, String id, String file) {
        this.handler = handler;
        context = handler.getApplicationContext();
        this.id = id;
        this.audioFile = file;
        this.tempFiles = new LinkedList<String>();

    }

    /**
     * Creates an audio file path from the provided fileName or creates a new temporary file path.
     *
     * @param fileName the audio file name, if null a temporary 3gp file name is provided
     * @return String
     */
    private String createAudioFilePath(String fileName) {
        File dir = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)
            ? context.getExternalFilesDir(null)
            : context.getCacheDir();

        fileName = (fileName == null || fileName.isEmpty())
            ? String.format("tmprecording-%d.3gp", System.currentTimeMillis())
            : fileName;

        return dir.getAbsolutePath() + File.separator + fileName;
    }

    /**
     * Destroy player and stop audio playing or recording.
     */
    public void destroy() {
        // Stop any play or record
        if (this.player != null) {
            if ((this.state == STATE.MEDIA_RUNNING) || (this.state == STATE.MEDIA_PAUSED)) {
                this.player.stop();
                this.setState(STATE.MEDIA_STOPPED);
            }
            this.player.release();
            this.player = null;
        }
        if (this.recorder != null) {
            if (this.state != STATE.MEDIA_STOPPED) {
                this.stopRecording(true);
            }
            this.recorder.release();
            this.recorder = null;
        }
    }

    /**
     * Start recording the specified file.
     *
     * @param file              The name of the file
     */
    public void startRecording(String file) {
        String errorMessage;
        switch (this.mode) {
        case PLAY:
            errorMessage = "AudioPlayer Error: Can't record in play mode.";
            sendErrorStatus(MEDIA_ERR_ABORTED, errorMessage);
            break;
        case NONE:
            this.audioFile = file;
            this.recorder = new MediaRecorder();
            this.recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            this.recorder.setOutputFormat(MediaRecorder.OutputFormat.AAC_ADTS); // RAW_AMR);
            this.recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); //AMR_NB);
            this.tempFile = createAudioFilePath(null);
            this.recorder.setOutputFile(this.tempFile);
            try {
                this.recorder.prepare();
                this.recorder.start();
                this.setState(STATE.MEDIA_RUNNING);
                return;
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            sendErrorStatus(MEDIA_ERR_ABORTED, null);
            break;
        case RECORD:
            errorMessage = "AudioPlayer Error: Already recording.";
            sendErrorStatus(MEDIA_ERR_ABORTED, errorMessage);
        }
    }

    /**
     * Save temporary recorded file to specified name
     *
     * @param file
     */
    public void moveFile(String file) {
        /* this is a hack to save the file as the specified name */

        if (!file.startsWith("/")) {
            file = createAudioFilePath(file);
        }

        int size = this.tempFiles.size();
        LOG.d(LOG_TAG, "size = " + size);

        // only one file so just copy it
        if (size == 1) {
            String logMsg = "renaming " + this.tempFile + " to " + file;
            LOG.d(LOG_TAG, logMsg);

            File f = new File(this.tempFile);
            if (!f.renameTo(new File(file))) {

                FileOutputStream outputStream = null;
                File outputFile = null;
                try {
                    outputFile = new File(file);
                    outputStream = new FileOutputStream(outputFile);
                    FileInputStream inputStream = null;
                    File inputFile = null;
                    try {
                        inputFile = new File(this.tempFile);
                        LOG.d(LOG_TAG,  "INPUT FILE LENGTH: " + String.valueOf(inputFile.length()) );
                        inputStream = new FileInputStream(inputFile);
                        copy(inputStream, outputStream, false);
                    } catch (Exception e) {
                        LOG.e(LOG_TAG, e.getLocalizedMessage(), e);
                   } finally {
                        if (inputStream != null) try {
                            inputStream.close();
                            inputFile.delete();
                            inputFile = null;
                        } catch (Exception e) {
                            LOG.e(LOG_TAG, e.getLocalizedMessage(), e);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (outputStream != null) try {
                        outputStream.close();
                        LOG.d(LOG_TAG, "OUTPUT FILE LENGTH: " + String.valueOf(outputFile.length()) );
                    } catch (Exception e) {
                        LOG.e(LOG_TAG, e.getLocalizedMessage(), e);
                    }
                }
            }
        }
        // more than one file so the user must have pause recording. We'll need to concat files.
        else {
          FileOutputStream outputStream = null;
          try {
              outputStream = new FileOutputStream(new File(file));
              FileInputStream inputStream = null;
              File inputFile = null;
              for (int i = 0; i < size; i++) {
                  try {
                      inputFile = new File(this.tempFiles.get(i));
                      inputStream = new FileInputStream(inputFile);
                      copy(inputStream, outputStream, (i>0));
                  } catch(Exception e) {
                      LOG.e(LOG_TAG, e.getLocalizedMessage(), e);
                  } finally {
                      if (inputStream != null) try {
                          inputStream.close();
                          inputFile.delete();
                          inputFile = null;
                      } catch (Exception e) {
                          LOG.e(LOG_TAG, e.getLocalizedMessage(), e);
                      }
                  }
              }
          } catch(Exception e) {
              e.printStackTrace();
          } finally {
              if (outputStream != null) try {
                  outputStream.close();
              } catch (Exception e) {
                  LOG.e(LOG_TAG, e.getLocalizedMessage(), e);
              }
          }
        }
    }

    private static long copy(InputStream from, OutputStream to, boolean skipHeader)
                throws IOException {
        byte[] buf = new byte[8096];
        long total = 0;
        if (skipHeader) {
            from.skip(6);
        }
        while (true) {
            int r = from.read(buf);
            if (r == -1) {
                break;
            }
            to.write(buf, 0, r);
            total += r;
        }
        return total;
    }

    /**
     * Stop/Pause recording and save to the file specified when recording started.
     */
    public void stopRecording(boolean stop) {
        if (this.recorder != null) {
            try{
                if (this.state == STATE.MEDIA_RUNNING) {
                    this.recorder.stop();
                }
                this.recorder.reset();
                if (!this.tempFiles.contains(this.tempFile)) {
                    this.tempFiles.add(this.tempFile);
                }
                if (stop) {
                    LOG.d(LOG_TAG, "stopping recording");
                    this.setState(STATE.MEDIA_STOPPED);
                    this.moveFile(this.audioFile);
                } else {
                    LOG.d(LOG_TAG, "pause recording");
                    this.setState(STATE.MEDIA_PAUSED);
                }
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * Resume recording and save to the file specified when recording started.
     */
    public void resumeRecording() {
        startRecording(this.audioFile);
    }

    //==========================================================================
    // Playback
    //==========================================================================

    /**
     * Start or resume playing audio file.
     *
     * @param file              The name of the audio file.
     */
    public void startPlaying(String file) {
        if (this.readyPlayer(file) && this.player != null) {
            this.player.start();
            this.setState(STATE.MEDIA_RUNNING);
            this.seekOnPrepared = 0; //insures this is always reset
        } else {
            this.prepareOnly = false;
        }
    }

    /**
     * Seek or jump to a new time in the track.
     */
    public void seekToPlaying(int milliseconds) {
        if (this.readyPlayer(this.audioFile)) {
            if (milliseconds > 0) {
                this.player.seekTo(milliseconds);
            }
            LOG.d(LOG_TAG, "Send a onStatus update for the new seek");
            sendStatusChange(MEDIA_POSITION, null, (milliseconds / 1000.0f), null);
        }
        else {
            this.seekOnPrepared = milliseconds;
        }
    }

    /**
     * Pause playing.
     */
    public void pausePlaying() {

        // If playing, then pause
        if (this.state == STATE.MEDIA_RUNNING && this.player != null) {
            this.player.pause();
            this.setState(STATE.MEDIA_PAUSED);
        }
        else {
            String errorMessage = "AudioPlayer Error: pausePlaying() called during invalid state: " + this.state.ordinal();
            sendErrorStatus(MEDIA_ERR_NONE_ACTIVE, errorMessage);
        }
    }

    /**
     * Stop playing the audio file.
     */
    public void stopPlaying() {
        if ((this.state == STATE.MEDIA_RUNNING) || (this.state == STATE.MEDIA_PAUSED)) {
            this.player.pause();
            this.player.seekTo(0);
            LOG.d(LOG_TAG, "stopPlaying is calling stopped");
            this.setState(STATE.MEDIA_STOPPED);
        }
        else {
            String errorMessage = "AudioPlayer Error: stopPlaying() called during invalid state: " + this.state.ordinal();
            sendErrorStatus(MEDIA_ERR_NONE_ACTIVE, errorMessage);
        }
    }

    /**
     * Resume playing.
     */
    public void resumePlaying() {
    	this.startPlaying(this.audioFile);
    }

    /**
     * Callback to be invoked when playback of a media source has completed.
     *
     * @param player           The MediaPlayer that reached the end of the file
     */
    public void onCompletion(MediaPlayer player) {
        LOG.d(LOG_TAG, "on completion is calling stopped");
        this.setState(STATE.MEDIA_STOPPED);
    }

    /**
     * Get current position of playback.
     *
     * @return                  position in msec or -1 if not playing
     */
    public long getCurrentPosition() {
        if ((this.state == STATE.MEDIA_RUNNING) || (this.state == STATE.MEDIA_PAUSED)) {
            int curPos = this.player.getCurrentPosition();
            sendStatusChange(MEDIA_POSITION, null, (curPos / 1000.0f), null);
            return curPos;
        }
        else {
            return -1;
        }
    }

    /**
     * Determine if playback file is streaming or local.
     * It is streaming if file name starts with "http://"
     *
     * @param file              The file name
     * @return                  T=streaming, F=local
     */
    public boolean isStreaming(String file) {
        if (file.contains("http://") || file.contains("https://") || file.contains("rtsp://")) {
            return true;
        }
        else {
            return false;
        }
    }

    /**
      * Get the duration of the audio file.
      *
      * @param file             The name of the audio file.
      * @return                 The duration in msec.
      *                             -1=can't be determined
      *                             -2=not allowed
      */
    public float getDuration(String file) {

        // Can't get duration of recording
        if (this.recorder != null) {
            return (-2); // not allowed
        }

        // If audio file already loaded and started, then return duration
        if (this.player != null) {
            return this.duration;
        }

        // If no player yet, then create one
        else {
            this.prepareOnly = true;
            this.startPlaying(file);

            // This will only return value for local, since streaming
            // file hasn't been read yet.
            return this.duration;
        }
    }

    /**
     * Callback to be invoked when the media source is ready for playback.
     *
     * @param player           The MediaPlayer that is ready for playback
     */
    public void onPrepared(MediaPlayer player) {
        // Listen for playback completion
        this.player.setOnCompletionListener(this);
        // seek to any location received while not prepared
        this.seekToPlaying(this.seekOnPrepared);
        // apply any playback rate received while not prepared
        if (setRateOnPrepared >= 0)
            this.player.setPlaybackParams (this.player.getPlaybackParams().setSpeed(setRateOnPrepared));
        // If start playing after prepared
        if (!this.prepareOnly) {
            this.player.start();
            this.setState(STATE.MEDIA_RUNNING);
            this.seekOnPrepared = 0; //reset only when played
        } else {
            this.setState(STATE.MEDIA_STARTING);
        }
        // Save off duration
        this.duration = getDurationInSeconds();
        // reset prepare only flag
        this.prepareOnly = true;

        // Send status notification to JavaScript
        sendStatusChange(MEDIA_DURATION, null, this.duration, null);
    }

    /**
     * By default Android returns the length of audio in mills but we want seconds
     *
     * @return length of clip in seconds
     */
    private float getDurationInSeconds() {
        return (this.player.getDuration() / 1000.0f);
    }

    /**
     * Callback to be invoked when there has been an error during an asynchronous operation
     *  (other errors will throw exceptions at method call time).
     *
     * @param player           the MediaPlayer the error pertains to
     * @param arg1              the type of error that has occurred: (MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_SERVER_DIED)
     * @param arg2              an extra code, specific to the error.
     */
    public boolean onError(MediaPlayer player, int arg1, int arg2) {
        String errorMessage = "AudioPlayer.onError(" + arg1 + ", " + arg2 + ")";

        // we don't want to send success callback
        // so we don't call setState() here
        this.state = STATE.MEDIA_STOPPED;
        this.destroy();
        // Send error notification to JavaScript
        sendErrorStatus(arg1, errorMessage);

        return false;
    }

    /**
     * Set the state and send it to JavaScript.
     *
     * @param state
     */
    private void setState(STATE state) {
        if (this.state != state) {
            sendStatusChange(MEDIA_STATE, null, (float)state.ordinal(), null);
        }
        this.state = state;
    }

    /**
     * Set the mode and send it to JavaScript.
     *
     * @param mode
     */
    private void setMode(MODE mode) {
        if (this.mode != mode) {
            //mode is not part of the expected behavior, so no notification
            //this.handler.webView.sendJavascript("cordova.require('cordova-plugin-media.Media').onStatus('" + this.id + "', " + MEDIA_STATE + ", " + mode + ");");
        }
        this.mode = mode;
    }

    /**
     * Get the audio state.
     *
     * @return int
     */
    public int getState() {
        return this.state.ordinal();
    }

    /**
     * Set the volume for audio player
     *
     * @param volume
     */
    public void setVolume(float volume) {
        if (this.player != null) {
            this.player.setVolume(volume, volume);
        } else {
            String errorMessage = "AudioPlayer Error: Cannot set volume until the audio file is initialized.";
            sendErrorStatus(MEDIA_ERR_NONE_ACTIVE, errorMessage);
        }
    }

    /**
     * attempts to put the player in play mode
     * @return true if in playmode, false otherwise
     */
    private boolean playMode() {
        switch(this.mode) {
        case NONE:
            this.setMode(MODE.PLAY);
            break;
        case PLAY:
            break;
        case RECORD:
            String errorMessage = "AudioPlayer Error: Can't play in record mode.";
            sendErrorStatus(MEDIA_ERR_ABORTED, errorMessage);
            return false; //player is not ready
        }
        return true;
    }

    /**
     * attempts to initialize the media player for playback
     * @param file the file to play
     * @return false if player not ready, reports if in wrong mode or state
     */
    private boolean readyPlayer(String file) {
        if (playMode()) {
            switch (this.state) {
                case MEDIA_NONE:
                    if (this.player == null) {
                        this.player = new MediaPlayer();
                        this.player.setOnErrorListener(this);
                    }
                    try {
                        this.loadAudioFile(file);
                    } catch (Exception e) {
                        sendErrorStatus(MEDIA_ERR_ABORTED, e.getMessage());
                    }
                    return false;
                case MEDIA_LOADING:
                    //cordova js is not aware of MEDIA_LOADING, so we send MEDIA_STARTING instead
                    LOG.d(LOG_TAG, "AudioPlayer Loading: startPlaying() called during media preparation: " + STATE.MEDIA_STARTING.ordinal());
                    this.prepareOnly = false;
                    return false;
                case MEDIA_STARTING:
                case MEDIA_RUNNING:
                case MEDIA_PAUSED:
                    return true;
                case MEDIA_STOPPED:
                    //if we are readying the same file
                    if (file!=null && this.audioFile.compareTo(file) == 0) {
                        //maybe it was recording?
                        if (player == null) {
                            this.player = new MediaPlayer();
                            this.player.setOnErrorListener(this);
                            this.prepareOnly = false;

                            try {
                                this.loadAudioFile(file);
                            } catch (Exception e) {
                                sendErrorStatus(MEDIA_ERR_ABORTED, e.getMessage());
                            }
                            return false;//we´re not ready yet
                        }
                        else {
                           //reset the audio file
                            player.seekTo(0);
                            player.pause();
                            return true;
                        }
                    } else {
                        //reset the player
                        this.player.reset();
                        try {
                            this.loadAudioFile(file);
                        } catch (Exception e) {
                            sendErrorStatus(MEDIA_ERR_ABORTED, e.getMessage());
                        }
                        //if we had to prepare the file, we won't be in the correct state for playback
                        return false;
                    }
                default:
                    String errorMessage = "AudioPlayer Error: startPlaying() called during invalid state: " + this.state;
                    sendErrorStatus(MEDIA_ERR_ABORTED, errorMessage);
            }
        }
        return false;
    }

    /**
     * load audio file
     * @throws IOException
     * @throws IllegalStateException
     * @throws SecurityException
     * @throws IllegalArgumentException
     */
    private void loadAudioFile(String file) throws IllegalArgumentException, SecurityException, IllegalStateException, IOException {
        if (this.isStreaming(file)) {
            this.player.setDataSource(file);
            this.player.setAudioStreamType(AudioManager.STREAM_MUSIC);
            //if it's a streaming file, play mode is implied
            this.setMode(MODE.PLAY);
            this.setState(STATE.MEDIA_STARTING);
            this.player.setOnPreparedListener(this);
            this.player.prepareAsync();
        }
        else {
            if (file.startsWith("/android_asset/")) {
                String f = file.substring(15);
                android.content.res.AssetFileDescriptor fd = this.handler.cordova.getActivity().getAssets().openFd(f);
                this.player.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
            }
            else {
                File fp = new File(file);
                if (fp.exists()) {
                    FileInputStream fileInputStream = new FileInputStream(file);
                    this.player.setDataSource(fileInputStream.getFD());
                    fileInputStream.close();
                }
                else {
                    this.player.setDataSource(createAudioFilePath(file));
                }
            }
                this.setState(STATE.MEDIA_STARTING);
                this.player.setOnPreparedListener(this);
                this.player.prepare();

                // Get duration
                this.duration = getDurationInSeconds();
            }
    }

    private void sendErrorStatus(int errorCode, String errorMessage) {
        sendStatusChange(MEDIA_ERROR, errorCode, null, errorMessage);
    }

    private void sendStatusChange(int messageType, Integer additionalCode, Float value, String errorMessage) {
        if (additionalCode != null && value != null) {
            throw new IllegalArgumentException("Only one of additionalCode or value can be specified, not both");
        }

        if (errorMessage != null) {
            LOG.d(LOG_TAG, errorMessage);
        }

        JSONObject statusDetails = new JSONObject();
        try {
            statusDetails.put("id", this.id);
            statusDetails.put("msgType", messageType);
            if (additionalCode != null) {
                JSONObject code = new JSONObject();
                code.put("code", additionalCode.intValue());

                if (errorMessage != null) {
                    code.put("message", errorMessage);
                }

                statusDetails.put("value", code);
            }
            else if (value != null) {
                statusDetails.put("value", value.floatValue());
            }
        } catch (JSONException e) {
            LOG.e(LOG_TAG, "Failed to create status details", e);
        }

        this.handler.sendEventMessage("status", statusDetails);
    }

    /**
     * Get current amplitude of recording.
     *
     * @return amplitude or 0 if not recording
     */
    public float getCurrentAmplitude() {
        if (this.recorder != null) {
            try{
                if (this.state == STATE.MEDIA_RUNNING) {
                    return (float) this.recorder.getMaxAmplitude() / 32762;
                }
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
        return 0;
    }

    /**
     * Set the playback rate for the player (ignored on API < 23)
     *
     * @param volume
     */
    public void setRate(float rate) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            LOG.d(LOG_TAG, "AudioPlayer Warning: Request to set playback rate not supported on current OS version");
            return;
        }

        if (this.player != null) {
            try {
                boolean wasPlaying = this.player.isPlaying();

                this.player.setPlaybackParams(this.player.getPlaybackParams().setSpeed(rate));

                if (!wasPlaying && this.player.isPlaying()) {
                    this.player.pause();
                }
            } catch(Exception e) {
                e.printStackTrace();
            }
        } else {
            setRateOnPrepared = rate;
        }
    }
}
