/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies).
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/


#include "avfmediarecordercontrol_ios.h"
#include "avfcamerarenderercontrol.h"
#include "avfcamerasession.h"
#include "avfcameracontrol.h"
#include "avfcameraservice.h"
#include "avfcameradebug.h"
#include "avfaudioencodersettingscontrol.h"
#include "avfvideoencodersettingscontrol.h"
#include "avfmediacontainercontrol.h"
#include "avfcamerautility.h"

#include <QtCore/qmath.h>
#include <QtCore/qdebug.h>

QT_USE_NAMESPACE

namespace {

bool qt_is_writable_file_URL(NSURL *fileURL)
{
    Q_ASSERT(fileURL);

    if (![fileURL isFileURL])
        return false;

    if (NSString *path = [[fileURL path] stringByExpandingTildeInPath]) {
        return [[NSFileManager defaultManager]
                isWritableFileAtPath:[path stringByDeletingLastPathComponent]];
    }

    return false;
}

bool qt_file_exists(NSURL *fileURL)
{
    Q_ASSERT(fileURL);

    if (NSString *path = [[fileURL path] stringByExpandingTildeInPath])
        return [[NSFileManager defaultManager] fileExistsAtPath:path];

    return false;
}

}

AVFMediaRecorderControlIOS::AVFMediaRecorderControlIOS(AVFCameraService *service, QObject *parent)
    : QMediaRecorderControl(parent)
    , m_service(service)
    , m_state(QMediaRecorder::StoppedState)
    , m_lastStatus(QMediaRecorder::UnloadedStatus)
    , m_audioSettings(nil)
    , m_videoSettings(nil)
{
    Q_ASSERT(service);

    m_writer.reset([[QT_MANGLE_NAMESPACE(AVFMediaAssetWriter) alloc] initWithDelegate:this]);
    if (!m_writer) {
        qDebugCamera() << Q_FUNC_INFO << "failed to create an asset writer";
        return;
    }

    AVFCameraControl *cameraControl = m_service->cameraControl();
    if (!cameraControl) {
        qDebugCamera() << Q_FUNC_INFO << "camera control is nil";
        return;
    }

    connect(cameraControl, SIGNAL(captureModeChanged(QCamera::CaptureModes)),
                           SLOT(captureModeChanged(QCamera::CaptureModes)));
    connect(cameraControl, SIGNAL(statusChanged(QCamera::Status)),
                           SLOT(cameraStatusChanged(QCamera::Status)));
}

AVFMediaRecorderControlIOS::~AVFMediaRecorderControlIOS()
{
    [m_writer abort];

    if (m_audioSettings)
        [m_audioSettings release];
    if (m_videoSettings)
        [m_videoSettings release];
}

QUrl AVFMediaRecorderControlIOS::outputLocation() const
{
    return m_outputLocation;
}

bool AVFMediaRecorderControlIOS::setOutputLocation(const QUrl &location)
{
    m_outputLocation = location;
    return location.scheme() == QLatin1String("file") || location.scheme().isEmpty();
}

QMediaRecorder::State AVFMediaRecorderControlIOS::state() const
{
    return m_state;
}

QMediaRecorder::Status AVFMediaRecorderControlIOS::status() const
{
    return m_lastStatus;
}

qint64 AVFMediaRecorderControlIOS::duration() const
{
    return m_writer.data().durationInMs;
}

bool AVFMediaRecorderControlIOS::isMuted() const
{
    return false;
}

qreal AVFMediaRecorderControlIOS::volume() const
{
    return 1.;
}

void AVFMediaRecorderControlIOS::applySettings()
{
    AVFCameraSession *session = m_service->session();
    if (!session)
        return;

    if (m_state != QMediaRecorder::StoppedState
            || (session->state() != QCamera::ActiveState && session->state() != QCamera::LoadedState)
            || !m_service->cameraControl()->captureMode().testFlag(QCamera::CaptureVideo)) {
        return;
    }

    // audio settings
    m_audioSettings = m_service->audioEncoderSettingsControl()->applySettings();
    if (m_audioSettings)
        [m_audioSettings retain];

    // video settings
    AVCaptureConnection *conn = [m_service->videoOutput()->videoDataOutput() connectionWithMediaType:AVMediaTypeVideo];
    m_videoSettings = m_service->videoEncoderSettingsControl()->applySettings(conn);
    if (m_videoSettings)
        [m_videoSettings retain];
}

void AVFMediaRecorderControlIOS::unapplySettings()
{
    m_service->audioEncoderSettingsControl()->unapplySettings();

    AVCaptureConnection *conn = [m_service->videoOutput()->videoDataOutput() connectionWithMediaType:AVMediaTypeVideo];
    m_service->videoEncoderSettingsControl()->unapplySettings(conn);

    if (m_audioSettings) {
        [m_audioSettings release];
        m_audioSettings = nil;
    }
    if (m_videoSettings) {
        [m_videoSettings release];
        m_videoSettings = nil;
    }
}

void AVFMediaRecorderControlIOS::setState(QMediaRecorder::State state)
{
    Q_ASSERT(m_service->session()
             && m_service->session()->captureSession());

    if (!m_writer) {
        qDebugCamera() << Q_FUNC_INFO << "Invalid recorder";
        return;
    }

    if (state == m_state)
        return;

    switch (state) {
    case QMediaRecorder::RecordingState:
    {
        AVFCameraControl *cameraControl = m_service->cameraControl();
        Q_ASSERT(cameraControl);

        if (!(cameraControl->captureMode() & QCamera::CaptureVideo)) {
            qDebugCamera() << Q_FUNC_INFO << "wrong capture mode, CaptureVideo expected";
            Q_EMIT error(QMediaRecorder::ResourceError, tr("Failed to start recording"));
            return;
        }

        if (cameraControl->status() != QCamera::ActiveStatus) {
            qDebugCamera() << Q_FUNC_INFO << "can not start record while camera is not active";
            Q_EMIT error(QMediaRecorder::ResourceError, tr("Failed to start recording"));
            return;
        }

        const QString path(m_outputLocation.scheme() == QLatin1String("file") ?
                           m_outputLocation.path() : m_outputLocation.toString());
        const QUrl fileURL(QUrl::fromLocalFile(m_storageLocation.generateFileName(path, QCamera::CaptureVideo,
                           QLatin1String("clip_"),
                           m_service->mediaContainerControl()->containerFormat())));

        NSURL *nsFileURL = fileURL.toNSURL();
        if (!nsFileURL) {
            qWarning() << Q_FUNC_INFO << "invalid output URL:" << fileURL;
            Q_EMIT error(QMediaRecorder::ResourceError, tr("Invalid output file URL"));
            return;
        }
        if (!qt_is_writable_file_URL(nsFileURL)) {
            qWarning() << Q_FUNC_INFO << "invalid output URL:" << fileURL
                       << "(the location is not writable)";
            Q_EMIT error(QMediaRecorder::ResourceError, tr("Non-writeable file location"));
            return;
        }
        if (qt_file_exists(nsFileURL)) {
            // We test for/handle this error here since AWAssetWriter will raise an
            // Objective-C exception, which is not good at all.
            qWarning() << Q_FUNC_INFO << "invalid output URL:" << fileURL
                       << "(file already exists)";
            Q_EMIT error(QMediaRecorder::ResourceError, tr("File already exists"));
            return;
        }

        AVCaptureSession *session = m_service->session()->captureSession();
        // We stop session now so that no more frames for renderer's queue
        // generated, will restart in assetWriterStarted.
        [session stopRunning];

        applySettings();

        // Make sure the video is recorded in device orientation.
        // The top of the video will match the side of the device which is on top
        // when recording starts (regardless of the UI orientation).
        AVFCameraInfo cameraInfo = m_service->session()->activeCameraInfo();
        int screenOrientation = 360 - m_orientationHandler.currentOrientation();
        float rotation = 0;
        if (cameraInfo.position == QCamera::FrontFace)
            rotation = (screenOrientation + cameraInfo.orientation) % 360;
        else
            rotation = (screenOrientation + (360 - cameraInfo.orientation)) % 360;

        if ([m_writer setupWithFileURL:nsFileURL
                      cameraService:m_service
                      audioSettings:m_audioSettings
                      videoSettings:m_videoSettings
                      transform:CGAffineTransformMakeRotation(qDegreesToRadians(rotation))]) {

            m_state = QMediaRecorder::RecordingState;
            m_lastStatus = QMediaRecorder::StartingStatus;

            Q_EMIT actualLocationChanged(fileURL);
            Q_EMIT stateChanged(m_state);
            Q_EMIT statusChanged(m_lastStatus);

            // Apple recommends to call startRunning and do all
            // setup on a special queue, and that's what we had
            // initially (dispatch_async to writerQueue). Unfortunately,
            // writer's queue is not the only queue/thread that can
            // access/modify the session, and as a result we have
            // all possible data/race-conditions with Obj-C exceptions
            // at best and something worse in general.
            // Now we try to only modify session on the same thread.
            [m_writer start];
        } else {
            [session startRunning];
            Q_EMIT error(QMediaRecorder::FormatError, tr("Failed to start recording"));
        }
    } break;
    case QMediaRecorder::PausedState:
    {
        Q_EMIT error(QMediaRecorder::FormatError, tr("Recording pause not supported"));
        return;
    } break;
    case QMediaRecorder::StoppedState:
    {
        // Do not check the camera status, we can stop if we started.
        stopWriter();
    }
    }
}

void AVFMediaRecorderControlIOS::setMuted(bool muted)
{
    Q_UNUSED(muted)
    qDebugCamera() << Q_FUNC_INFO << "not implemented";
}

void AVFMediaRecorderControlIOS::setVolume(qreal volume)
{
    Q_UNUSED(volume)
    qDebugCamera() << Q_FUNC_INFO << "not implemented";
}

void AVFMediaRecorderControlIOS::assetWriterStarted()
{
    m_lastStatus = QMediaRecorder::RecordingStatus;
    Q_EMIT statusChanged(QMediaRecorder::RecordingStatus);
}

void AVFMediaRecorderControlIOS::assetWriterFinished()
{
    AVFCameraControl *cameraControl = m_service->cameraControl();
    Q_ASSERT(cameraControl);

    const QMediaRecorder::Status lastStatus = m_lastStatus;
    const QMediaRecorder::State lastState = m_state;
    if (cameraControl->captureMode() & QCamera::CaptureVideo)
        m_lastStatus = QMediaRecorder::LoadedStatus;
    else
        m_lastStatus = QMediaRecorder::UnloadedStatus;

    unapplySettings();

    m_service->videoOutput()->resetCaptureDelegate();
    [m_service->session()->captureSession() startRunning];
    m_state = QMediaRecorder::StoppedState;
    if (m_lastStatus != lastStatus)
        Q_EMIT statusChanged(m_lastStatus);
    if (m_state != lastState)
        Q_EMIT stateChanged(m_state);
}

void AVFMediaRecorderControlIOS::captureModeChanged(QCamera::CaptureModes newMode)
{
    AVFCameraControl *cameraControl = m_service->cameraControl();
    Q_ASSERT(cameraControl);

    const QMediaRecorder::Status lastStatus = m_lastStatus;

    if (newMode & QCamera::CaptureVideo) {
        if (cameraControl->status() == QCamera::ActiveStatus)
            m_lastStatus = QMediaRecorder::LoadedStatus;
    } else {
        if (m_lastStatus == QMediaRecorder::RecordingStatus)
           return stopWriter();
        else
            m_lastStatus = QMediaRecorder::UnloadedStatus;
    }

    if (m_lastStatus != lastStatus)
        Q_EMIT statusChanged(m_lastStatus);
}

void AVFMediaRecorderControlIOS::cameraStatusChanged(QCamera::Status newStatus)
{
    AVFCameraControl *cameraControl = m_service->cameraControl();
    Q_ASSERT(cameraControl);

    const QMediaRecorder::Status lastStatus = m_lastStatus;
    const bool isCapture = cameraControl->captureMode() & QCamera::CaptureVideo;
    if (newStatus == QCamera::StartingStatus) {
        if (isCapture && m_lastStatus == QMediaRecorder::UnloadedStatus)
            m_lastStatus = QMediaRecorder::LoadingStatus;
    } else if (newStatus == QCamera::ActiveStatus) {
        if (isCapture && m_lastStatus == QMediaRecorder::LoadingStatus)
            m_lastStatus = QMediaRecorder::LoadedStatus;
    } else {
        if (m_lastStatus == QMediaRecorder::RecordingStatus)
            return stopWriter();
        if (newStatus == QCamera::UnloadedStatus)
            m_lastStatus = QMediaRecorder::UnloadedStatus;
    }

    if (lastStatus != m_lastStatus)
        Q_EMIT statusChanged(m_lastStatus);
}

void AVFMediaRecorderControlIOS::stopWriter()
{
    if (m_lastStatus == QMediaRecorder::RecordingStatus) {
        m_lastStatus = QMediaRecorder::FinalizingStatus;

        Q_EMIT statusChanged(m_lastStatus);

        [m_writer stop];
    }
}

#include "moc_avfmediarecordercontrol_ios.cpp"
