/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed 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.
 */

#include <dlfcn.h>
#include <stdio.h>
#include <unistd.h>
#include <utils/Log.h>
#include <utils/threads.h>
#include <VideoEditorClasses.h>
#include <VideoEditorJava.h>
#include <VideoEditorOsal.h>
#include <VideoEditorLogging.h>
#include <VideoEditorOsal.h>
#include <marker.h>

extern "C" {
#include <M4OSA_Clock.h>
#include <M4OSA_CharStar.h>
#include <M4OSA_Error.h>
#include <M4OSA_FileCommon.h>
#include <M4OSA_FileReader.h>
#include <M4OSA_FileWriter.h>
#include <M4OSA_Memory.h>
#include <M4OSA_String.h>
#include <M4OSA_Thread.h>
#include <M4VSS3GPP_API.h>
#include <M4VSS3GPP_ErrorCodes.h>
#include <M4MCS_API.h>
#include <M4MCS_ErrorCodes.h>
#include <M4MDP_API.h>
#include <M4READER_Common.h>
#include <M4WRITER_common.h>
#include <M4DECODER_Common.h>
#include <M4AD_Common.h>
};

extern "C" M4OSA_ERR M4MCS_open_normalMode(
                M4MCS_Context                       pContext,
                M4OSA_Void*                         pFileIn,
                M4VIDEOEDITING_FileType             InputFileType,
                M4OSA_Void*                         pFileOut,
                M4OSA_Void*                         pTempFile);

jobject videoEditProp_getProperties(
                JNIEnv*                             pEnv,
                jobject                             thiz,
                jstring                             file);

static void
getFileAndMediaTypeFromExtension (
                M4OSA_Char* pExtension,
                VideoEditClasses_FileType   *pFileType,
                M4VIDEOEDITING_FileType       *pClipType);

static M4OSA_ERR
getClipProperties(  JNIEnv*                         pEnv,
                    jobject                         thiz,
                    M4OSA_Char*                     pFile,
                    M4VIDEOEDITING_FileType         clipType,
                    M4VIDEOEDITING_ClipProperties*  pClipProperties);

M4OSA_UInt32
VideoEdit_chrCompare(M4OSA_Char* pStrIn1,
                     M4OSA_Char* pStrIn2,
                     M4OSA_Int32* pCmpResult);

jobject videoEditProp_getProperties(
        JNIEnv* pEnv,
        jobject thiz,
        jstring file)
{
    bool                           gotten          = true;
    M4OSA_Char*                    pFile           = M4OSA_NULL;
    M4OSA_Char*                    pExtension      = M4OSA_NULL;
    M4OSA_UInt32                   index           = 0;
    M4OSA_Int32                    cmpResult       = 0;
    VideoEditPropClass_Properties* pProperties     = M4OSA_NULL;
    M4VIDEOEDITING_ClipProperties* pClipProperties = M4OSA_NULL;
    M4OSA_ERR                      result          = M4NO_ERROR;
    M4MCS_Context                  context         = M4OSA_NULL;
    M4OSA_FilePosition             size            = 0;
    M4OSA_UInt32                   width           = 0;
    M4OSA_UInt32                   height          = 0;
    jobject                        properties      = NULL;
    M4OSA_Context                  pOMXContext     = M4OSA_NULL;
    M4DECODER_VideoInterface*      pOMXVidDecoderInterface = M4OSA_NULL;
    M4AD_Interface*                pOMXAudDecoderInterface = M4OSA_NULL;

    bool  initialized = true;
    VideoEditClasses_FileType fileType = VideoEditClasses_kFileType_Unsupported;
    M4VIDEOEDITING_FileType clipType = M4VIDEOEDITING_kFileType_Unsupported;

    VIDEOEDIT_LOG_API(
            ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES",
            "videoEditProp_getProperties()");

    // Add a text marker (the condition must always be true).
    ADD_TEXT_MARKER_FUN(NULL != pEnv)

    // Initialize the classes.
    videoEditPropClass_init(&initialized, (JNIEnv*)pEnv);

    // Validate the tempPath parameter.
    videoEditJava_checkAndThrowIllegalArgumentException(
            &gotten, pEnv, (NULL == file), "file is null");

    // Get the file path.
    pFile = (M4OSA_Char *)videoEditJava_getString(
            &gotten, pEnv, file, NULL, M4OSA_NULL);

    result = M4OSA_fileReadOpen(&context, (M4OSA_Void*)pFile, M4OSA_kFileRead);

    if(M4NO_ERROR != result) {
        // Free the file path.
        videoEditOsal_free(pFile);
        pFile = M4OSA_NULL;
    }

    videoEditJava_checkAndThrowIllegalArgumentException(&gotten, pEnv,
        (M4NO_ERROR != result), "file not found");

    // Close the file and free the file context
    if (context != NULL) {
        result = M4OSA_fileReadClose(context);
        context = M4OSA_NULL;
    }

    // Return if Error
    if (M4NO_ERROR != result) {
        return (properties); // NULL
    }

    // Check if the file path is valid.
    if (gotten)
    {
        // Retrieve the extension.
        result = M4OSA_chrReverseFindChar(pFile, '.', &pExtension);
        if ((M4NO_ERROR == result) && (M4OSA_NULL != pExtension))
        {
            // Skip the dot.
            pExtension++;

            // Get the file type and Media type from extension
            getFileAndMediaTypeFromExtension(
                    pExtension ,&fileType, &clipType);
        }
    }

    // Check if the file type could be determined.
    videoEditJava_checkAndThrowIllegalArgumentException(
            &gotten, pEnv,
            (VideoEditClasses_kFileType_Unsupported == fileType),
            "file type is not supported");

    // Allocate a new properties structure.
    pProperties = (VideoEditPropClass_Properties*)videoEditOsal_alloc(
            &gotten, pEnv,
            sizeof(VideoEditPropClass_Properties), "Properties");

    // Check if the context is valid and allocation succeeded
    // (required because of dereferencing of pProperties).
    if (gotten)
    {
        // Check if this type of file needs to be analyzed using MCS.
        if ((VideoEditClasses_kFileType_MP3  == fileType) ||
            (VideoEditClasses_kFileType_MP4  == fileType) ||
            (VideoEditClasses_kFileType_3GPP == fileType) ||
            (VideoEditClasses_kFileType_AMR  == fileType) ||
            (VideoEditClasses_kFileType_PCM  == fileType) ||
            (VideoEditClasses_kFileType_M4V  == fileType))
        {
            // Allocate a new clip properties structure.
            pClipProperties =
                (M4VIDEOEDITING_ClipProperties*)videoEditOsal_alloc(
                    &gotten, pEnv,
                    sizeof(M4VIDEOEDITING_ClipProperties), "ClipProperties");

            // Check if allocation succeeded (required because of
            // dereferencing of pClipProperties).
            if (gotten)
            {
                // Add a code marker (the condition must always be true).
                ADD_CODE_MARKER_FUN(NULL != pClipProperties)

                // Log the API call.
                VIDEOEDIT_LOG_API(
                        ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES",
                        "getClipProperties");

                // Get Video clip properties
                result = getClipProperties(
                        pEnv, thiz, pFile, clipType, pClipProperties);

                if (M4MCS_ERR_FILE_DRM_PROTECTED == result) {
                    // Check if the creation succeeded.
                    videoEditJava_checkAndThrowIllegalArgumentException(
                            &gotten, pEnv,(M4NO_ERROR != result),
                            "Invalid File - DRM Protected ");
                } else {
                    // Check if the creation succeeded.
                    videoEditJava_checkAndThrowIllegalArgumentException(
                            &gotten, pEnv,(M4NO_ERROR != result),
                            "Invalid File or File not found ");
                }

                /**
                 * Max resolution supported is 1280 x 720.
                 */
                if ( (pClipProperties->uiVideoWidth > 1280)
                    || (pClipProperties->uiVideoHeight > 720) )
                {
                    result = M4MCS_ERR_INVALID_INPUT_VIDEO_FRAME_SIZE;
                    videoEditJava_checkAndThrowIllegalArgumentException(
                            &gotten, pEnv, (M4NO_ERROR != result),
                            "Unsupported input video frame size");
                }

#ifdef USE_SOFTWARE_DECODER
                /**
                 * Input clip with non-multiples of 16 is not supported.
                 */
                if ( (pClipProperties->uiVideoWidth %16)
                    || (pClipProperties->uiVideoHeight %16) )
                {
                    result = M4MCS_ERR_INPUT_VIDEO_SIZE_NON_X16;
                    videoEditJava_checkAndThrowIllegalArgumentException(
                            &gotten, pEnv, (M4NO_ERROR != result),
                            "non x16 input video frame size is not supported");
                }
#endif /* USE_SOFTWARE_DECODER */
            }

            // Check if the properties could be retrieved.
            if (gotten)
            {
                // Set the properties.
                pProperties->uiClipDuration = pClipProperties->uiClipDuration;
                if (M4VIDEOEDITING_kFileType_Unsupported == pClipProperties->FileType)
                {
                    pProperties->FileType        = VideoEditClasses_kFileType_Unsupported;
                }
                else
                {
                    pProperties->FileType        = fileType;
                }
                pProperties->VideoStreamType     = pClipProperties->VideoStreamType;
                pProperties->uiClipVideoDuration = pClipProperties->uiClipVideoDuration;
                pProperties->uiVideoBitrate      = pClipProperties->uiVideoBitrate;
                pProperties->uiVideoWidth        = pClipProperties->uiVideoWidth;
                pProperties->uiVideoHeight       = pClipProperties->uiVideoHeight;
                pProperties->fAverageFrameRate   = pClipProperties->fAverageFrameRate;
                pProperties->ProfileAndLevel     = pClipProperties->ProfileAndLevel;
                pProperties->AudioStreamType     = pClipProperties->AudioStreamType;
                pProperties->uiClipAudioDuration = pClipProperties->uiClipAudioDuration;
                pProperties->uiAudioBitrate      = pClipProperties->uiAudioBitrate;
                pProperties->uiNbChannels        = pClipProperties->uiNbChannels;
                pProperties->uiSamplingFrequency = pClipProperties->uiSamplingFrequency;
            }

            // Free the clip properties.
            videoEditOsal_free(pClipProperties);
            pClipProperties = M4OSA_NULL;
        }
        else if ((VideoEditClasses_kFileType_JPG == fileType) ||
            (VideoEditClasses_kFileType_GIF == fileType) ||
            (VideoEditClasses_kFileType_PNG == fileType))
        {
            pProperties->uiClipDuration      = 0;
            pProperties->FileType            = fileType;
            pProperties->VideoStreamType     = M4VIDEOEDITING_kNoneVideo;
            pProperties->uiClipVideoDuration = 0;
            pProperties->uiVideoBitrate      = 0;
            pProperties->uiVideoWidth        = width;
            pProperties->uiVideoHeight       = height;
            pProperties->fAverageFrameRate   = 0.0f;
            pProperties->ProfileAndLevel     = M4VIDEOEDITING_kProfile_and_Level_Out_Of_Range;
            pProperties->AudioStreamType     = M4VIDEOEDITING_kNoneAudio;
            pProperties->uiClipAudioDuration = 0;
            pProperties->uiAudioBitrate      = 0;
            pProperties->uiNbChannels        = 0;
            pProperties->uiSamplingFrequency = 0;

            // Added for Handling invalid paths and non existent image files
            // Open the file for reading.
            result = M4OSA_fileReadOpen(&context, (M4OSA_Void*)pFile, M4OSA_kFileRead);
            if (M4NO_ERROR != result)
            {
                pProperties->FileType = VideoEditClasses_kFileType_Unsupported;
            }
            result = M4OSA_fileReadClose(context);
            context = M4OSA_NULL;
        }
    }

    // Create a properties object.
    videoEditPropClass_createProperties(&gotten, pEnv, pProperties, &properties);

    // Log the properties.
    VIDEOEDIT_PROP_LOG_PROPERTIES(pProperties);

    // Free the properties.
    videoEditOsal_free(pProperties);
    pProperties = M4OSA_NULL;

    // Free the file path.
    videoEditOsal_free(pFile);
    pFile = M4OSA_NULL;

    // Add a text marker (the condition must always be true).
    ADD_TEXT_MARKER_FUN(NULL != pEnv)

    // Return the Properties object.
    return(properties);
}

static void getFileAndMediaTypeFromExtension (
        M4OSA_Char *pExtension,
        VideoEditClasses_FileType *pFileType,
        M4VIDEOEDITING_FileType *pClipType)
{
    M4OSA_Char extension[5] = {0, 0, 0, 0, 0};
    VideoEditClasses_FileType fileType =
            VideoEditClasses_kFileType_Unsupported;

    M4VIDEOEDITING_FileType clipType =
            M4VIDEOEDITING_kFileType_Unsupported;

    M4OSA_UInt32 index = 0;
    M4OSA_ERR result = M4NO_ERROR;
    M4OSA_Int32 cmpResult = 0;
    M4OSA_UInt32  extLength = M4OSA_chrLength(pExtension);

    // Assign default
    *pFileType = VideoEditClasses_kFileType_Unsupported;
    *pClipType = M4VIDEOEDITING_kFileType_Unsupported;

    // Check if the length of the extension is valid.
    if ((3 == extLength) || (4 == extLength))
    {
        // Convert the extension to lowercase.
        for (index = 0; index < extLength ; index++)
        {
            extension[index] = M4OSA_chrToLower(pExtension[index]);
        }

        // Check if the extension is ".mp3".
        if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"mp3", &cmpResult)))
        {
            *pFileType = VideoEditClasses_kFileType_MP3;
            *pClipType = M4VIDEOEDITING_kFileType_MP3;
        }
        // Check if the extension is ".mp4".
        else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"mp4", &cmpResult)))
        {
            *pFileType = VideoEditClasses_kFileType_MP4;
            *pClipType = M4VIDEOEDITING_kFileType_MP4;
        }
        // Check if the extension is ".3gp".
        else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"3gp", &cmpResult)))
        {
            *pFileType = VideoEditClasses_kFileType_3GPP;
            *pClipType = M4VIDEOEDITING_kFileType_3GPP;
        }
        // Check if the extension is ".m4a".
        else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"m4a", &cmpResult)))
        {
            *pFileType = VideoEditClasses_kFileType_3GPP;
            *pClipType = M4VIDEOEDITING_kFileType_3GPP;
        }
        // Check if the extension is ".3gpp".
        else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"3gpp", &cmpResult)))
        {
            *pFileType = VideoEditClasses_kFileType_3GPP;
            *pClipType = M4VIDEOEDITING_kFileType_3GPP;
        }
        // Check if the extension is ".amr".
        else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"amr", &cmpResult)))
        {
            *pFileType = VideoEditClasses_kFileType_AMR;
            *pClipType = M4VIDEOEDITING_kFileType_AMR;
        }
        // Check if the extension is ".pcm".
        else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"pcm", &cmpResult)))
        {
            *pFileType = VideoEditClasses_kFileType_PCM;
            *pClipType = M4VIDEOEDITING_kFileType_PCM;
        }
        // Check if the extension is ".jpg".
        else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"jpg", &cmpResult)))
        {
            *pFileType = VideoEditClasses_kFileType_JPG;
        }
        // Check if the extension is ".jpeg".
        else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"jpeg", &cmpResult)))
        {
            *pFileType = VideoEditClasses_kFileType_JPG;
        }
        // Check if the extension is ".gif".
        else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"gif", &cmpResult)))
        {
            *pFileType = VideoEditClasses_kFileType_GIF;
        }
        // Check if the extension is ".png".
        else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"png", &cmpResult)))
        {
            *pFileType = VideoEditClasses_kFileType_PNG;
        }
        // Check if the extension is ".m4v".
        else if (!(VideoEdit_chrCompare(extension, (M4OSA_Char*)"m4v", &cmpResult)))
        {
            *pFileType = VideoEditClasses_kFileType_M4V;
            *pClipType = M4VIDEOEDITING_kFileType_M4V;
        }
    }
}

static M4OSA_ERR getClipProperties(
        JNIEnv* pEnv,
        jobject thiz,
        M4OSA_Char* pFile,
        M4VIDEOEDITING_FileType clipType,
        M4VIDEOEDITING_ClipProperties* pClipProperties)
{
    bool                      gotten          = true;
    M4OSA_ERR                 result          = M4NO_ERROR;
    M4OSA_ERR                 resultAbort     = M4NO_ERROR;
    M4MCS_Context             context         = M4OSA_NULL;

    M4OSA_FileReadPointer fileReadPtr =
            { M4OSA_NULL, M4OSA_NULL, M4OSA_NULL,
              M4OSA_NULL, M4OSA_NULL, M4OSA_NULL };

    M4OSA_FileWriterPointer fileWritePtr =
            { M4OSA_NULL, M4OSA_NULL, M4OSA_NULL,
              M4OSA_NULL, M4OSA_NULL, M4OSA_NULL, M4OSA_NULL };

    // Initialize the OSAL file system function pointers.
    videoEditOsal_getFilePointers(&fileReadPtr , &fileWritePtr);

    // Log the API call.
    VIDEOEDIT_LOG_API(
            ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES",\
            "getClipProperties - M4MCS_init()");

    // Initialize the MCS context.
    result = M4MCS_init(&context, &fileReadPtr, &fileWritePtr);

    // Log the result.
    VIDEOEDIT_PROP_LOG_RESULT(
            ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES", "%s",
            videoEditOsal_getResultString(result));

    // Check if the creation succeeded.
    videoEditJava_checkAndThrowRuntimeException(
            &gotten, pEnv, (M4NO_ERROR != result), result);

    // Check if opening the MCS context succeeded.
    if (gotten)
    {
        // Log the API call.
        VIDEOEDIT_LOG_API(
                ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES",
                "getClipProperties - M4MCS_open_normalMode()");

        // Open the MCS in the normal opening mode to
        // retrieve the exact duration
        result = M4MCS_open_normalMode(
                context, pFile, clipType, M4OSA_NULL, M4OSA_NULL);

        // Log the result.
        VIDEOEDIT_PROP_LOG_RESULT(
                ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES", "%s",
                videoEditOsal_getResultString(result));

        // Check if the creation succeeded.
        videoEditJava_checkAndThrowRuntimeException(
                &gotten, pEnv, (M4NO_ERROR != result), result);

        // Check if the MCS could be opened.
        if (gotten)
        {
            // Log the API call.
            VIDEOEDIT_LOG_API(
                    ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES",
                    "getClipProperties - M4MCS_getInputFileProperties()");

            // Get the properties.
            result = M4MCS_getInputFileProperties(context, pClipProperties);

            // Log the result.
            VIDEOEDIT_PROP_LOG_RESULT(
                    ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES", "%s",
                    videoEditOsal_getResultString(result));

            // Check if the creation succeeded.
            videoEditJava_checkAndThrowRuntimeException(
                    &gotten, pEnv, (M4NO_ERROR != result), result);
        }

        // Log the API call.
        VIDEOEDIT_LOG_API(
                ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES",
                "getClipProperties - M4MCS_abort()");

        // Close the MCS session.
        resultAbort = M4MCS_abort(context);

       if (result == M4NO_ERROR) {
            // Log the result.
            VIDEOEDIT_PROP_LOG_RESULT(
                    ANDROID_LOG_INFO, "VIDEO_EDITOR_PROPERTIES", "%s",
                    videoEditOsal_getResultString(resultAbort));

            // Check if the abort succeeded.
            videoEditJava_checkAndThrowRuntimeException(
                    &gotten, pEnv, (M4NO_ERROR != resultAbort), resultAbort);
            result = resultAbort;
        }
    }

    return result;
}

M4OSA_UInt32
VideoEdit_chrCompare(M4OSA_Char* pStrIn1,
                     M4OSA_Char* pStrIn2,
                      M4OSA_Int32* pCmpResult)
{
    M4OSA_chrCompare(pStrIn1, pStrIn2, pCmpResult);
    return *pCmpResult;
}


