<?php
/**
 * Created by PhpStorm.
 * User: crose
 * Date: 4/17/17
 * Time: 5:51 PM
 *
 * Check: CODING.md > Download
 */

namespace IMATHUZH\Qfq\Api;

require_once(__DIR__ . '/../../vendor/autoload.php');

use IMATHUZH\Qfq\Core\Exception\ErrorHandler;
use IMATHUZH\Qfq\Core\Helper\DownloadProgress;
use IMATHUZH\Qfq\Core\Helper\Support;
use IMATHUZH\Qfq\Core\Report\Download;

// Detect API calls if this is defined. Do not try use "const QFQ_API 'Api call'" in Constansts.php : this will break detection of API Calls
define('QFQ_API', 'Api call');

set_error_handler("\\IMATHUZH\\Qfq\\Core\\Exception\\ErrorHandler::exception_error_handler");

$output = '';
$isModal = false;

try {
    try {
        ErrorHandler::useAsPhpErrorHandler();

        $isModal = $_GET[DOWNLOAD_MODAL_API_PARAMETER] ?? false;
        $downloadProgress = null;

        if ($isModal === DOWNLOAD_MODAL_GET_STATUS || $isModal === DOWNLOAD_MODAL_GET_DELETE_FILE) {
            $jobId = $_GET[DOWNLOAD_MODAL_GET_JOBID] ?? false;
            $downloadProgress = new DownloadProgress($jobId);
        }

        switch ($isModal) {

            //JS Step 1: Calculate timing
            case DOWNLOAD_MODAL_GET_TIMING:
                $downloadMode = $_GET[DOWNLOAD_MODAL_GET_MODE] ?? false;
                $answer = $downloadMode ? DownloadProgress::readTimingJson($downloadMode) : [];
                break;

            //JS Step 2: Status polling ('complete' answer finished polling)
            case DOWNLOAD_MODAL_GET_STATUS:
                $answer = $downloadProgress->downloadProgressStatus();
                $answer = $answer ?: [
                    DOWNLOAD_MODAL_GET_STATUS => DOWNLOAD_MODAL_STATUS_PREPARING,
                    DOWNLOAD_MODAL_STATUS_CURRENT_FILES => 0,
                    DOWNLOAD_MODAL_STATUS_TOTAL_FILES => 0,
                ];
                break;

            //JS Step 3: Delete progress File
            case DOWNLOAD_MODAL_GET_DELETE_FILE:
                $answer = $downloadProgress->deleteProgressFile();
                break;
        }

        if (isset($answer)) {
            header('Content-Type: application/json');
            echo json_encode($answer);
            exit;
        }

        if ($isModal === DOWNLOAD_MODAL_PREPARE_FILE) {
            $jobId = $_GET[DOWNLOAD_MODAL_GET_JOBID] ?? false;
            $downloadProgress = new DownloadProgress($jobId);
        }
        $download = new Download();

        // If all is fine: process() will output file via print() !!
        $output = $download->process(STORE_SIP, OUTPUT_MODE_DIRECT, $isModal, $downloadProgress);

    } catch (\CodeException $e) {
        if ($isModal) {
            $msg = json_decode($e->getMessage(), true);
            header('Content-Type: application/json');
            $output = json_encode(['success' => false, 'error' => $msg[ERROR_MESSAGE_TO_USER] ?? 'Download failed']);
        } else {
            $output = $e->formatMessage();
        }
    } catch (\DbException $e) {
        if ($isModal) {
            $msg = json_decode($e->getMessage(), true);
            header('Content-Type: application/json');
            $output = json_encode(['success' => false, 'error' => $msg[ERROR_MESSAGE_TO_USER] ?? 'Download failed']);
        } else {
            $output = $e->formatMessage();
        }

    } catch (\DownloadException $e) {
        if ($isModal) {
            $msg = json_decode($e->getMessage(), true);
            $userMsg = $e->getCode() === ERROR_IO_FILE_NOT_FOUND ? ($msg[ERROR_MESSAGE_TO_USER] ?? 'File not found') : 'Download failed';
            header('Content-Type: application/json');
            $output = json_encode(['success' => false, 'error' => $userMsg]);
        } else {
            $output = $e->formatMessage();
        }

    }
} catch (\Throwable $e) {

    $wrapped = Support::wrapUnexpectedException($e);
    try {
        if ($isModal) {
            header('Content-Type: application/json');
            $output = json_encode(['success' => false, 'error' => 'Download failed']);
        } else {
            $output = $wrapped->formatException();
        }
    } catch (\Throwable $exception) {
        header('Content-Type: application/json');
        $output = json_encode(['success' => false, 'error' => 'Download failed']);
    }
}

echo $output;