package fr.ensisa.lob.supercallrecorder;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.content.BroadcastReceiver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.media.AudioManager;
import android.media.MediaRecorder;
import android.os.Environment;
import android.telecom.TelecomManager;
import android.telephony.TelephonyManager;
import android.util.Log;

public class CallHandler extends BroadcastReceiver {


    /*
    DEBUG TAG
     */
    private static final String TAG = "CallHandler";

    /*
    CONFIG
     */
    private static final String RECORD_FOLDER = "RECORD";
    private static final String FORMAT = ".amr"; //".3gp";

    /*
    record -> contains the conversation
    recordedData -> metadata
    path -> file's path
     */
    private static MediaRecorder record;
    private static Record recordedData;
    private static String path = "";
    private static boolean incoming;
    private static String lastState = "";
    private static boolean recording = false;



    public void onReceive(Context context, Intent intent) {



        if (intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")) {
            if (!recording) {
                startRecording(intent);
            }
            lastState = "RINGING";
            return;
        }

        String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);


        switch (state)
        {
            case "OFFHOOK":
                incoming = lastState.equals("RINGING");

                if (!recording)
                {
                    startRecording(intent);
                }

                break;
            case "IDLE" :

                try {
                    stopRecording(context);

                } catch (Exception e)
                {
                    Log.e(TAG,state);
                }


                break;
            case "RINGING" :
            default:

                break;
        }
        lastState = state;
    }



    public void startRecording(Intent intent)
    {
        if (recording)
            return;
        record = new MediaRecorder();
        this.recording = true;

        try {

            record.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION);
            record.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
            record.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

            path = getFilename();

            String phoneNumber="";
            if (intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER) != null)
            {
                phoneNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
            } else
            {
                phoneNumber =intent.getExtras().getString("android.intent.extra.PHONE_NUMBER");
            }
            recordedData = new Record(path,new Date(),incoming,phoneNumber);
            record.setOutputFile(path);
            record.setOnErrorListener(errorListener);
            record.setOnInfoListener(infoListener);

        } catch (Exception e)
        {
            Log.e(TAG,"CONFIGURATION FAILURE : "+e.getMessage());
        }

        try {
            record.prepare();
            record.start();
        } catch (Exception e)
        {
            Log.e(TAG,"PREPARATION FAILURE : "+e.getMessage());
            e.printStackTrace();
        }

    }

    public void saveIntoDB(Context ctx)
    {
        RecordDbHelper mDbHelper = new RecordDbHelper(ctx);
        SQLiteDatabase db = mDbHelper.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put(RecordDbHelper.RecordEntry.COLUMN_NAME_CONTACTNAME, recordedData.getContactName());
        values.put(RecordDbHelper.RecordEntry.COLUMN_NAME_INCOMING, recordedData.isIncoming());
        values.put(RecordDbHelper.RecordEntry.COLUMN_NAME_DATE, recordedData.getDate().toString());
        values.put(RecordDbHelper.RecordEntry.COLUMN_NAME_FILENAME, recordedData.getFileName());
        values.put(RecordDbHelper.RecordEntry.COLUMN_NAME_SALT, recordedData.getSalt());
        db.insert(RecordDbHelper.RecordEntry.TABLE_NAME, null, values);
        db.close();
    }

    public void stopRecording(Context ctx)
    {
        this.recording = false;
        try {
            if (record != null)
            {
                saveIntoDB(ctx);
                record.stop();
                record.reset();
                record.release();

            }
        } catch (Exception e)
        {
            Log.e(TAG,"STOP FAILURE : "+e.getMessage());

        }

    }
    private String getFilename() {
        String filepath = Environment.getExternalStorageDirectory().getPath();
        File file = new File(filepath, RECORD_FOLDER);

        if (!file.exists()) {
            file.mkdirs();
        }

        return (file.getAbsolutePath() + "/" + new SimpleDateFormat("yyyy-MM-dd-hh-mm-ss").format(new Date())+FORMAT);

    }

    private MediaRecorder.OnErrorListener errorListener = new MediaRecorder.OnErrorListener() {
        @Override
        public void onError(MediaRecorder mr, int what, int extra) {
            Log.e(TAG,"Error: " + what + ", " + extra);

        }
    };

    private MediaRecorder.OnInfoListener infoListener = new MediaRecorder.OnInfoListener() {
        @Override
        public void onInfo(MediaRecorder mr, int what, int extra) {
            Log.e(TAG, "Warning: " + what + ", " + extra);

        }
    };

}
