/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

//
// vie_autotest_file.cc
//

#include "vie_autotest_defines.h"
#include "vie_autotest.h"
#include "engine_configurations.h"

#include "tb_interfaces.h"
#include "tb_capture_device.h"

#include "voe_codec.h"

class ViEAutotestFileObserver: public webrtc::ViEFileObserver
{
public:
    ViEAutotestFileObserver() {};
    ~ViEAutotestFileObserver() {};

    void PlayFileEnded(const WebRtc_Word32 fileId)
    {
        ViETest::Log("PlayFile ended");
    }
};

void ViEAutoTest::ViEFileStandardTest()
{
#ifdef WEBRTC_VIDEO_ENGINE_FILE_API
    //***************************************************************
    //	Begin create/initialize WebRTC Video Engine for testing
    //***************************************************************
    {
        ViETest::Log("Starting a loopback call...");

        TbInterfaces interfaces = TbInterfaces("ViEFileStandardTest");

        webrtc::VideoEngine* ptrViE = interfaces.video_engine;
        webrtc::ViEBase* ptrViEBase = interfaces.base;
        webrtc::ViECapture* ptrViECapture = interfaces.capture;
        webrtc::ViERender* ptrViERender = interfaces.render;
        webrtc::ViECodec* ptrViECodec = interfaces.codec;
        webrtc::ViERTP_RTCP* ptrViERtpRtcp = interfaces.rtp_rtcp;
        webrtc::ViENetwork* ptrViENetwork = interfaces.network;

        TbCaptureDevice captureDevice = TbCaptureDevice(interfaces);
        int captureId = captureDevice.captureId;

        int videoChannel = -1;
        EXPECT_EQ(0, ptrViEBase->CreateChannel(videoChannel));
        EXPECT_EQ(0, ptrViECapture->ConnectCaptureDevice(
            captureId, videoChannel));

        EXPECT_EQ(0, ptrViERtpRtcp->SetRTCPStatus(
            videoChannel, webrtc::kRtcpCompound_RFC4585));
        EXPECT_EQ(0, ptrViERtpRtcp->SetKeyFrameRequestMethod(
            videoChannel, webrtc::kViEKeyFrameRequestPliRtcp));
        EXPECT_EQ(0, ptrViERtpRtcp->SetTMMBRStatus(videoChannel, true));

        EXPECT_EQ(0, ptrViERender->AddRenderer(
            captureId, _window1, 0, 0.0, 0.0, 1.0, 1.0));
        EXPECT_EQ(0, ptrViERender->AddRenderer(
            videoChannel, _window2, 1, 0.0, 0.0, 1.0, 1.0));
        EXPECT_EQ(0, ptrViERender->StartRender(captureId));
        EXPECT_EQ(0, ptrViERender->StartRender(videoChannel));

        webrtc::VideoCodec videoCodec;
        memset(&videoCodec, 0, sizeof(webrtc::VideoCodec));
        for (int idx = 0; idx < ptrViECodec->NumberOfCodecs(); idx++)
        {
            EXPECT_EQ(0, ptrViECodec->GetCodec(idx, videoCodec));
            EXPECT_EQ(0, ptrViECodec->SetReceiveCodec(videoChannel,
                                                      videoCodec));
        }

        // Find the codec used for encoding the channel
        for (int idx = 0; idx < ptrViECodec->NumberOfCodecs(); idx++)
        {
            EXPECT_EQ(0, ptrViECodec->GetCodec(idx, videoCodec));
            if (videoCodec.codecType == webrtc::kVideoCodecVP8)
            {
                EXPECT_EQ(0, ptrViECodec->SetSendCodec(videoChannel, videoCodec));
                break;
            }
        }
        // Find the codec used for recording.
        for (int idx = 0; idx < ptrViECodec->NumberOfCodecs(); idx++)
        {
            EXPECT_EQ(0, ptrViECodec->GetCodec(idx, videoCodec));
            if (videoCodec.codecType == webrtc::kVideoCodecI420)
            {
                break;
            }
        }


        const char* ipAddress = "127.0.0.1";
        const unsigned short rtpPort = 6000;
        EXPECT_EQ(0, ptrViENetwork->SetLocalReceiver(videoChannel, rtpPort));
        EXPECT_EQ(0, ptrViEBase->StartReceive(videoChannel));
        EXPECT_EQ(0, ptrViENetwork->SetSendDestination(
            videoChannel, ipAddress, rtpPort));
        EXPECT_EQ(0, ptrViEBase->StartSend(videoChannel));
        webrtc::ViEFile* ptrViEFile = webrtc::ViEFile::GetInterface(ptrViE);
        EXPECT_TRUE(ptrViEFile != NULL);

        webrtc::VoiceEngine* ptrVEEngine = webrtc::VoiceEngine::Create();
        webrtc::VoEBase* ptrVEBase = webrtc::VoEBase::GetInterface(ptrVEEngine);
        ptrVEBase->Init();

        int audioChannel = ptrVEBase->CreateChannel();
        ptrViEBase->SetVoiceEngine(ptrVEEngine);
        ptrViEBase->ConnectAudioChannel(videoChannel, audioChannel);

        webrtc::CodecInst audioCodec;
        webrtc::VoECodec* ptrVECodec =
            webrtc::VoECodec::GetInterface(ptrVEEngine);
        for (int index = 0; index < ptrVECodec->NumOfCodecs(); index++)
        {
            ptrVECodec->GetCodec(index, audioCodec);
            if (0 == strcmp(audioCodec.plname, "PCMU") || 0
                == strcmp(audioCodec.plname, "PCMA"))
            {
                break; // these two types are allowed as avi recording formats
            }
        }

        webrtc::CodecInst audioCodec2;

        //***************************************************************
        //	Engine ready. Begin testing class
        //***************************************************************

        // Call started
        ViETest::Log("Call started\nYou should see local preview from camera\n"
                     "in window 1 and the remote video in window 2.");
        AutoTestSleep(2000);

        const int RENDER_TIMEOUT = 1000;
        const int TEST_SPACING = 1000;
        const int VIDEO_LENGTH = 5000;


        const char renderStartImage[1024] =
            VIE_TEST_FILES_ROOT "renderStartImage.jpg";
        const char captureDeviceImage[1024] =
            VIE_TEST_FILES_ROOT "captureDeviceImage.jpg";
        const char renderTimeoutFile[1024] =
            VIE_TEST_FILES_ROOT "renderTimeoutImage.jpg";
        const char snapshotCaptureDeviceFileName[256] =
            VIE_TEST_FILES_ROOT "snapshotCaptureDevice.jpg";
        const char incomingVideo[1024] =
            VIE_TEST_FILES_ROOT "incomingVideo.avi";
        const char outgoingVideo[1024] =
            VIE_TEST_FILES_ROOT "outgoingVideo.avi";
        char snapshotRenderFileName[256] =
            VIE_TEST_FILES_ROOT "snapshotRenderer.jpg";

        webrtc::ViEPicture capturePicture;
        webrtc::ViEPicture renderPicture;
        webrtc::ViEPicture renderTimeoutPicture; // TODO: init with and image

        ViEAutotestFileObserver fileObserver;
        int fileId;

        AutoTestSleep(TEST_SPACING);

        // testing StartRecordIncomingVideo and StopRecordIncomingVideo
        {
            ViETest::Log("Recording incoming video (currently no audio) for %d "
                         "seconds", VIDEO_LENGTH);

            EXPECT_EQ(0, ptrViEFile->StartRecordIncomingVideo(
                videoChannel, incomingVideo, webrtc::NO_AUDIO,
                audioCodec2, videoCodec));

            AutoTestSleep(VIDEO_LENGTH);
            ViETest::Log("Stop recording incoming video");

            EXPECT_EQ(0, ptrViEFile->StopRecordIncomingVideo(videoChannel));
            ViETest::Log("Done\n");
        }

        AutoTestSleep(TEST_SPACING);

        // testing GetFileInformation
        {
            webrtc::VideoCodec fileVideoCodec;
            webrtc::CodecInst fileAudioCodec;
            ViETest::Log("Reading video file information");

            EXPECT_EQ(0, ptrViEFile->GetFileInformation(
                incomingVideo, fileVideoCodec, fileAudioCodec));
            PrintAudioCodec(fileAudioCodec);
            PrintVideoCodec(fileVideoCodec);
        }

        // testing StartPlayFile and RegisterObserver
        {
            ViETest::Log("Start playing file: %s with observer", incomingVideo);
            EXPECT_EQ(0, ptrViEFile->StartPlayFile(incomingVideo, fileId));

            ViETest::Log("Registering file observer");
            EXPECT_EQ(0, ptrViEFile->RegisterObserver(fileId, fileObserver));
            ViETest::Log("Done\n");
        }

        // testing SendFileOnChannel and StopSendFileOnChannel
        {
            ViETest::Log("Sending video on channel");
            // should fail since we are sending the capture device.
            EXPECT_NE(0, ptrViEFile->SendFileOnChannel(fileId, videoChannel));

            // Disconnect the camera
            EXPECT_EQ(0, ptrViECapture->DisconnectCaptureDevice(videoChannel));

            // And try playing the file again.
            EXPECT_EQ(0, ptrViEFile->SendFileOnChannel(fileId, videoChannel));

            AutoTestSleep(VIDEO_LENGTH);
            ViETest::Log("Stopped sending video on channel");
            EXPECT_EQ(0, ptrViEFile->StopSendFileOnChannel(videoChannel));
            ViETest::Log("Done\n");
        }

        AutoTestSleep(TEST_SPACING);

        // stop playing the file
        {
            ViETest::Log("Stop playing the file.");
            EXPECT_EQ(0, ptrViEFile->StopPlayFile(fileId));
            ViETest::Log("Done\n");
        }

        // testing StartRecordOutgoingVideo and StopRecordOutgoingVideo
        {
            // connect the camera to the output.
            EXPECT_EQ(0, ptrViECapture->ConnectCaptureDevice(
              captureId, videoChannel));

            ViETest::Log("Recording outgoing video (currently no audio) for %d "
                         "seconds", VIDEO_LENGTH);
            EXPECT_EQ(0, ptrViEFile->StartRecordOutgoingVideo(
                videoChannel, outgoingVideo, webrtc::NO_AUDIO,
                audioCodec2, videoCodec));

            AutoTestSleep(VIDEO_LENGTH);
            ViETest::Log("Stop recording outgoing video");
            EXPECT_EQ(0, ptrViEFile->StopRecordOutgoingVideo(videoChannel));
            ViETest::Log("Done\n");
        }

        // again testing GetFileInformation
        {
            EXPECT_EQ(0, ptrViEFile->GetFileInformation(
                incomingVideo, videoCodec, audioCodec2));
            PrintAudioCodec(audioCodec2);
            PrintVideoCodec(videoCodec);
        }

        AutoTestSleep(TEST_SPACING);

        // GetCaptureDeviceSnapshot
        {
            ViETest::Log("Testing GetCaptureDeviceSnapshot(int, ViEPicture)");
            ViETest::Log("Taking a picture to use for displaying ViEPictures "
                         "for the rest of file test");
            ViETest::Log("Hold an object to the camera. Ready?...");
            AutoTestSleep(1000);
            ViETest::Log("3");
            AutoTestSleep(1000);
            ViETest::Log("...2");
            AutoTestSleep(1000);
            ViETest::Log("...1");
            AutoTestSleep(1000);
            ViETest::Log("...Taking picture!");
            EXPECT_EQ(0, ptrViEFile->GetCaptureDeviceSnapshot(
                captureId, capturePicture));
            ViETest::Log("Picture has been taken.");
            AutoTestSleep(TEST_SPACING);

            ViETest::Log("Done\n");
        }

        AutoTestSleep(TEST_SPACING);

        // GetRenderSnapshot
        {
            ViETest::Log("Testing GetRenderSnapshot(int, char*)");

            ViETest::Log("Taking snapshot of videoChannel %d", captureId);
            EXPECT_EQ(0, ptrViEFile->GetRenderSnapshot(
                captureId, snapshotRenderFileName));
            ViETest::Log("Wrote image to file %s", snapshotRenderFileName);
            ViETest::Log("Done\n");
            AutoTestSleep(TEST_SPACING);
        }

        // GetRenderSnapshot
        {
            ViETest::Log("Testing GetRenderSnapshot(int, ViEPicture)");
            EXPECT_EQ(0, ptrViEFile->GetRenderSnapshot(
                captureId, renderPicture));
            ViETest::Log("Done\n");
        }

        AutoTestSleep(TEST_SPACING);

        // GetCaptureDeviceSnapshot
        {
            ViETest::Log("Testing GetCaptureDeviceSnapshot(int, char*)");
            ViETest::Log("Taking snapshot from capture device %d", captureId);
            EXPECT_EQ(0, ptrViEFile->GetCaptureDeviceSnapshot(
                captureId, snapshotCaptureDeviceFileName));
            ViETest::Log("Wrote image to file %s",
                         snapshotCaptureDeviceFileName);
            ViETest::Log("Done\n");
        }

        AutoTestSleep(TEST_SPACING);

        // Testing: SetCaptureDeviceImage
        {
            ViETest::Log("Testing SetCaptureDeviceImage(int, char*)");
            EXPECT_EQ(0, ptrViECapture->StopCapture(captureId));
            EXPECT_EQ(0, ptrViEFile->SetCaptureDeviceImage(
                captureId, captureDeviceImage));

            ViETest::Log("you should see the capture device image now");
            AutoTestSleep(2 * RENDER_TIMEOUT);
            EXPECT_EQ(0, ptrViECapture->StartCapture(captureId));
            ViETest::Log("Done\n");
        }

        AutoTestSleep(TEST_SPACING);

        // Testing: SetCaptureDeviceImage
        {
            ViETest::Log("Testing SetCaptureDeviceImage(int, ViEPicture)");
            EXPECT_EQ(0, ptrViECapture->StopCapture(captureId));
            EXPECT_EQ(0, ptrViEFile->SetCaptureDeviceImage(
                captureId, capturePicture));

            ViETest::Log("you should see the capture device image now");
            AutoTestSleep(2 * RENDER_TIMEOUT);
            EXPECT_EQ(0, ptrViECapture->StartCapture(captureId));
            ViETest::Log("Done\n");
        }

        AutoTestSleep(TEST_SPACING);

        // testing SetRenderStartImage(videoChannel, renderStartImage);
        {
            ViETest::Log("Testing SetRenderStartImage(int, char*)");
            // set render image, then stop capture and stop render to display it
            ViETest::Log("Stoping renderer, setting start image, then "
                         "restarting");
            EXPECT_EQ(0, ptrViEFile->SetRenderStartImage(
                videoChannel, renderStartImage));
            EXPECT_EQ(0, ptrViECapture->StopCapture(captureId));
            EXPECT_EQ(0, ptrViERender->StopRender(videoChannel));

            ViETest::Log("Render start image should be displayed.");
            AutoTestSleep(RENDER_TIMEOUT);

            // restarting capture and render
            EXPECT_EQ(0, ptrViECapture->StartCapture(captureId));
            EXPECT_EQ(0, ptrViERender->StartRender(videoChannel));
            ViETest::Log("Done\n");
        }

        AutoTestSleep(TEST_SPACING);

        // testing SetRenderStartImage(videoChannel, renderStartImage);
        {
            ViETest::Log("Testing SetRenderStartImage(int, ViEPicture)");
            // set render image, then stop capture and stop render to display it
            ViETest::Log("Stoping renderer, setting start image, then "
                         "restarting");
            EXPECT_EQ(0, ptrViEFile->SetRenderStartImage(
                videoChannel, capturePicture));
            EXPECT_EQ(0, ptrViECapture->StopCapture(captureId));
            EXPECT_EQ(0, ptrViERender->StopRender(videoChannel));

            ViETest::Log("Render start image should be displayed.");
            AutoTestSleep(RENDER_TIMEOUT);

            // restarting capture and render
            EXPECT_EQ(0, ptrViECapture->StartCapture(captureId));
            EXPECT_EQ(0, ptrViERender->StartRender(videoChannel));
            ViETest::Log("Done\n");
        }

        AutoTestSleep(TEST_SPACING);

        // testing SetRenderTimeoutImage(videoChannel, renderTimeoutFile,
        // RENDER_TIMEOUT);
        {
            ViETest::Log("Testing SetRenderTimeoutImage(int, char*)");
            ViETest::Log("Stopping capture device to induce timeout of %d ms",
                         RENDER_TIMEOUT);
            EXPECT_EQ(0, ptrViEFile->SetRenderTimeoutImage(
                videoChannel, renderTimeoutFile, RENDER_TIMEOUT));

            // now stop sending frames to the remote renderer and wait for
            // timeout
            EXPECT_EQ(0, ptrViECapture->StopCapture(captureId));
            AutoTestSleep(RENDER_TIMEOUT);
            ViETest::Log("Timeout image should be displayed now for %d ms",
                         RENDER_TIMEOUT * 2);
            AutoTestSleep(RENDER_TIMEOUT * 2);

            // restart the capture device to undo the timeout
            EXPECT_EQ(0, ptrViECapture->StartCapture(captureId));
            ViETest::Log("Restarting capture device");
            AutoTestSleep(RENDER_TIMEOUT);
            ViETest::Log("Done\n");
        }

        AutoTestSleep(TEST_SPACING);

        // Need to create a ViEPicture object to pass into this function.
        // SetRenderTimeoutImage(videoChannel, renderTimeoutFile,
        // RENDER_TIMEOUT);
        {
            ViETest::Log("Testing SetRenderTimeoutImage(int, ViEPicture)");
            ViETest::Log("Stopping capture device to induce timeout of %d",
                         RENDER_TIMEOUT);
            EXPECT_EQ(0, ptrViEFile->SetRenderTimeoutImage(
                videoChannel, capturePicture, RENDER_TIMEOUT));

            // now stop sending frames to the remote renderer and wait for
            // timeout
            EXPECT_EQ(0, ptrViECapture->StopCapture(captureId));
            AutoTestSleep(RENDER_TIMEOUT);
            ViETest::Log("Timeout image should be displayed now for %d",
                         RENDER_TIMEOUT * 2);
            AutoTestSleep(RENDER_TIMEOUT * 2);

            // restart the capture device to undo the timeout
            EXPECT_EQ(0, ptrViECapture->StartCapture(captureId));
            ViETest::Log("Restarting capture device");
            ViETest::Log("Done\n");
        }

        // testing DeregisterObserver
        {
            ViETest::Log("Deregistering file observer");
            // Should fail since we don't observe this file.
            EXPECT_NE(0, ptrViEFile->DeregisterObserver(fileId, fileObserver));
        }

        //***************************************************************
        //	Testing finished. Tear down Video Engine
        //***************************************************************

        EXPECT_EQ(0, ptrViEBase->DisconnectAudioChannel(videoChannel));
        EXPECT_EQ(0, ptrViEBase->SetVoiceEngine(NULL));
        EXPECT_EQ(0, ptrVEBase->DeleteChannel(audioChannel));
        EXPECT_EQ(0, ptrVEBase->Release());
        EXPECT_EQ(0, ptrVECodec->Release());
        EXPECT_TRUE(webrtc::VoiceEngine::Delete(ptrVEEngine));

        EXPECT_EQ(0, ptrViEBase->StopReceive(videoChannel));
        EXPECT_EQ(0, ptrViEBase->StopSend(videoChannel));
        EXPECT_EQ(0, ptrViERender->StopRender(videoChannel));
        EXPECT_EQ(0, ptrViERender->RemoveRenderer(captureId));
        EXPECT_EQ(0, ptrViERender->RemoveRenderer(videoChannel));
        EXPECT_EQ(0, ptrViECapture->DisconnectCaptureDevice(videoChannel));
        EXPECT_EQ(0, ptrViEFile->FreePicture(capturePicture));
        EXPECT_EQ(0, ptrViEFile->FreePicture(renderPicture));
        EXPECT_EQ(0, ptrViEFile->FreePicture(renderTimeoutPicture));
        EXPECT_EQ(0, ptrViEBase->DeleteChannel(videoChannel));

        EXPECT_EQ(0, ptrViEFile->Release());
    }
#endif
}

void ViEAutoTest::ViEFileExtendedTest()
{
}

void ViEAutoTest::ViEFileAPITest()
{
}
