<?php declare(strict_types=1);

require_once __DIR__ . '/QrbPdfData.php';
require_once __DIR__ . '/QrbMailData.php';
require_once __DIR__ . '/QrbCreditorInformation.php';
require_once __DIR__ . '/QrbAdditionalInformation.php';
require_once __DIR__ . '/QrbRecipient.php';

require_once __DIR__ . '/../common/QrbEnvironment.php';
require_once __DIR__ . '/../common/QrbException.php';
require_once __DIR__ . '/../common/QrbFiles.php';

// Validator for all QR bill input data.
final class QrbValidator
{

    // Validates the given file to be appropriate for the given file type.
    //
    // qrbDataType: QrbDataType
    // fileName:    full file name including path
    // extension:   file name extension
    // qrbCfg:      QrbProfileConfiguration, validation depends on concrete configuration
    //
    // Throws QrbException if file type is not known or validation fails.
    public static function validate(QrbDataType             $qrbDataType, 
                                    string                  $fileName, 
                                    string                  $extension, 
                                    QrbProfileConfiguration $qrbCfg) : void
    {
        // check extension
        switch ($qrbDataType)
        {
        case QrbDataType::PDF_TEMPLATE: self::checkPdf($extension);    break;
        case QrbDataType::PDF_DATA:
        case QrbDataType::CRED_INFO:
        case QrbDataType::ADD_INFO:
        case QrbDataType::MAIL_DATA:    self::checkJson($extension);   break;
        case QrbDataType::MAIL_BODY:    self::checkHtml($extension);   break;
        case QrbDataType::RECIPIENTS:   self::checkCsv($extension);    break;
        default:
            throw new QrbException(static::class . " - Invalid upload file.",
                                   "exception.upload.invalidUploadFile",
                                   $fileName);
        }
        
        // validate
        switch ($qrbDataType)
        {
        case QrbDataType::PDF_TEMPLATE: self::validatePdfTemplate($fileName, $qrbCfg); break;
        case QrbDataType::PDF_DATA:     self::validatePdfData($fileName, $qrbCfg);     break;
        case QrbDataType::CRED_INFO:    self::validateCredInfo($fileName, $qrbCfg);    break;
        case QrbDataType::ADD_INFO:     self::validateAddInfo($fileName, $qrbCfg);     break;
        case QrbDataType::MAIL_DATA:    self::validateMailData($fileName, $qrbCfg);    break;
        case QrbDataType::MAIL_BODY:    self::validateMailBody($fileName, $qrbCfg);    break;
        case QrbDataType::RECIPIENTS:   self::validateRecipients($fileName, $qrbCfg);  break;
        default:
            throw new QrbException(static::class . " - Invalid upload file.",
                                   "exception.upload.invalidUploadFile",
                                   $fileName);
        }
    }

    // Validates the PDF data input file.
    //
    // pdfDataFileName: full file name including path
    // qrbCfg:          QrbProfileConfiguration, validation depends on concrete configuration
    //
    // Throws QrbException if validation fails.
    private static function validatePdfData(string $pdfDataFileName, QrbProfileConfiguration $qrbCfg) : void
    {
        $pdfDataJson = QrbFiles::readJsonFile($pdfDataFileName);
        QrbPdfData::validate($pdfDataJson, $qrbCfg->getAdditionalLanguages());
    }
    
    // Validates the PDF template input file.
    //
    // pdfTemplateFileName: full file name including path
    // qrbCfg:              QrbProfileConfiguration, validation depends on concrete configuration
    //
    // Throws QrbException if validation fails.
    private static function validatePdfTemplate(string $pdfTemplateFileName, QrbProfileConfiguration $qrbCfg) : void
    {
        $pdfTemplate = 
            QrbFiles::readMultiLanguageText($pdfTemplateFileName, 
                                            QrbEnvironment::getSupportedLanguages(),
                                            $qrbCfg->getAdditionalLanguages());
        // no more checks at the moment
    }
    
    // Validates the creditor information input file.
    //
    // credInfoFileName: full file name including path
    // qrbCfg:           QrbProfileConfiguration, validation depends on concrete configuration
    //
    // Throws QrbException if validation fails.
    private static function validateCredInfo(string $credInfoFileName, QrbProfileConfiguration $qrbCfg) : void
    {
        $credInfoJson = QrbFiles::readJsonFile($credInfoFileName);
        QrbCreditorInformation::validate($credInfoJson);
    }
    
    // Validates the additional information input file.
    //
    // addInfoFileName: full file name including path
    // qrbCfg:          QrbProfileConfiguration, validation depends on concrete configuration
    //
    // Throws QrbException if validation fails.
    private static function validateAddInfo(string $addInfoFileName, QrbProfileConfiguration $qrbCfg) : void
    {
        $addInfoJson = QrbFiles::readJsonFile($addInfoFileName);
        QrbAdditionalInformation::validate($addInfoJson, 
                                              $qrbCfg->getAdditionalLanguages());
    }
    
    // Validates the mail data input file.
    //
    // mailDataFileName: full file name including path
    // qrbCfg:           QrbProfileConfiguration, validation depends on concrete configuration
    //
    // Throws QrbException if validation fails.
    private static function validateMailData(string $mailDataFileName, QrbProfileConfiguration $qrbCfg) : void
    {
        $mailDataJson = QrbFiles::readJsonFile($mailDataFileName);
        QrbMailData::validate($mailDataJson, $qrbCfg->getCreatePdf(), $qrbCfg->getAdditionalLanguages());
    }
    
    // Validates the mail body input file.
    //
    // mailBodyFileName: full file name including path
    // qrbCfg:           QrbProfileConfiguration, validation depends on concrete configuration
    //
    // Throws QrbException if validation fails.
    private static function validateMailBody(string $mailBodyFileName, QrbProfileConfiguration $qrbCfg) : void
    {
        $mailHtmlBody = 
            QrbFiles::readMultiLanguageText($mailBodyFileName, 
                                            QrbEnvironment::getSupportedLanguages(), 
                                            $qrbCfg->getAdditionalLanguages());
        // no more checks at the moment
    }
    
    // Validates the recipients input file.
    //
    // recipientsFileName: full file name including path
    // qrbCfg:             QrbProfileConfiguration, validation depends on concrete configuration
    //
    // Throws QrbException if validation fails.
    private static function validateRecipients(string $recipientsFileName, QrbProfileConfiguration $qrbCfg) : void
    {
        $recipientsData     = QrbFiles::readCsvFile($recipientsFileName);
        $recipientIndex     = 0;    
        $amountMandatory    = $qrbCfg->getPrintAmount() == QrbProfileConfiguration::INDIVIDUAL_AMOUNT;
        $createPdf          = $qrbCfg->getCreatePdf();
        $referenceMandatory = $qrbCfg->getPrintPaymentSlip();    // in fact not true if no QR IBAN ...
        $sendMail           = $qrbCfg->getSendMail();
        $supportedLanguages = QrbEnvironment::getSupportedLanguages();
        
        foreach ($recipientsData as $recipient)
        {
            if ($recipientIndex == 0)
            {
                $headerNames = 
                    QrbRecipient::parseHeader($recipient, 
                                              $amountMandatory, $createPdf, 
                                              $referenceMandatory, $sendMail);
            }
            else
            {
                QrbRecipient::validate($recipientIndex, $recipient, $headerNames,
                                       $amountMandatory, $createPdf, 
                                       $referenceMandatory, $sendMail, 
                                       $supportedLanguages);
            }
            
            $recipientIndex++;
        }
    }
    
    // Check if file type is JSON.
    //
    // fileType: file type (extension) to check
    //
    // Throws QrbException if file type is not appropriate for a JSON file.
    private static function checkJson(string $fileType) : void
    {
        if ($fileType != "json")
            throw new QrbException(static::class . " - Only JSON files are allowed",
                                   "exception.upload.onlyJsonFilesAllowed");
    }
    
    // Check if file type is PDF.
    //
    // fileType: file type (extension) to check
    //
    // Throws QrbException if file type is not appropriate for a ODF file.
    private static function checkPdf(string $fileType) : void
    {
        if ($fileType != "pdf")
            throw new QrbException(static::class . " - Only PDF files are allowed",
                                   "exception.upload.onlyPdfFilesAllowed");
    }
    
    // Check if file type is HTM or HTML.
    //
    // fileType: file type (extension) to check
    //
    // Throws QrbException if file type is not appropriate for a HTML file.
    private static function checkHtml(string $fileType) : void
    {
        if (($fileType != "htm") && ($fileType != "html"))
            throw new QrbException(static::class . " - Only HTM or HTML files are allowed.",
                                   "exception.upload.onlyHtmlFilesAllowed");
    }
    
    // Check if file type is CSV.
    //
    // fileType: file type (extension) to check
    //
    // Throws QrbException if file type is not appropriate for a CSV file.
    private static function checkCsv(string $fileType) : void
    {
        if ($fileType != "csv")
            throw new QrbException(static::class . " - Only CSV files are allowed",
                                   "exception.upload.onlyCsvFilesAllowed");
    }
}

?>
