<?php declare(strict_types=1);

require_once __DIR__ . '/../common/QrbDataType.php';
require_once __DIR__ . '/../data/QrbProfileConfiguration.php';
require_once __DIR__ . '/../data/QrbPdfData.php';
require_once __DIR__ . '/../data/QrbMailData.php';
require_once __DIR__ . '/../data/QrbCreditorInformation.php';
require_once __DIR__ . '/../data/QrbAdditionalInformation.php';
require_once __DIR__ . '/../data/QrbRecipient.php';
require_once __DIR__ . '/../data/QrbProtocolEntry.php';

// Interface to the storage mechanism.
interface QrbStorage
{
    // Sets maximum number of runs to keep.
    //
    // maxRunsToKeep: a positive number
    //
    // Throws QrbException if store fails.
    public function setMaxRunsToKeep(int $maxRunsToKeep) : void;
    
    // Returns maximum number of runs to keep.
    //
    // Returns a positive number.
    public function getMaxRunsToKeep() : int;


    // Writes the given message and optionally the additional lines to the log file.
    public function writeLog(string $message, ?array $additionaLines = NULL) : int|false;

    
    // Tries to get a lock for the current profile.
    //
    // Throws QrbLockedException if the lock can't be acquired.
    public function lockCurrentProfile();

    // Unlocks the current profile.
    public function unlockCurrentProfile();

    
    // Returns all profiles stored.
    public function getProfiles() : array; // of string

    // Returns the current profile.
    public function getCurrentProfile() : string;

    // Checks whether the given profile exists.    
    public function doesProfileExist(string $profile) : bool;

    // Makes the given profile the current one.
    //
    // profile: profile to select (one of the profiles returned by getCurrentProfile())
    //
    // Returns false if the given profile does not exist.
    //
    // Throws QrbException if storing selected profile fails.
    public function selectCurrentProfile(string $profile) : bool;

    // Creates a new profile and makes it the current one.
    //
    // profile: new profile to create
    //
    // Returns false if the given profile does already exist.
    //
    // Throws QrbException if storing new profile fails.
    public function createProfile(string $profile) : bool;

    // Deletes the profile with the given name and makes the default profile the current one.
    //
    // Returns false if the given profile is the default profile.
    //
    // Throws QrbException if storing default profile or deleting old profile fails.
    public function deleteProfile(string $profile) : bool;

    
    // Reads the configuration of the current profile.
    //
    // If the profile configuration is not found, creates a new instance and persists it.
    //
    // Throws QrbException if storing the new instance fails.
    public function getProfileConfiguration() : QrbProfileConfiguration;

    // Stores the given configuration as the configuration of the current profile.
    //
    // Throws QrbException if store fails.
    public function storeProfileConfiguration(QrbProfileConfiguration $qrbCfg) : void;


    // Deletes input data of the current profile, but not the profile itself. 
    //
    // Returns false if delete fails.
    public function deleteInputData() : bool;

    // Checks if the given input data exists and if so returns the relative path to the file.
    //
    // qrbDataType:  QrbDataType
    // language:     one of "de", "fr", "it", "en" or "" (no or default language)
    //
    // Returns NULL if file does not exist.
    public function checkInputDataExists(QrbDataType $qrbDataType, string $language) : ?string;

    // Stores the given input data.
    //
    // tmpFileName:  name as stored by PHP upload form
    // $qrbDataType: QrbDataType
    // language:     one of "de", "fr", "it", "en" or "" (no or default language)
    //
    // Throws QrbException if storing fails.
    public function storeInputData(string $tmpFileName, QrbDataType $qrbDataType, string $language) : void;

    // Reads PDF data and template from storage.
    //
    // Returns an instance of QrbPdfData.
    //
    // Throws QrbException if read fails.
    public function readPdfData(array $additionalLanguages) : QrbPdfData;

    // Reads mail data and body from storage.
    //
    // Returns an instance of QrbMailData.
    //
    // Throws QrbException if read fails.
    public function readMailData(array $additionalLanguages, bool $hasAttachment) : QrbMailData;

    // Reads creditor information from storaage.    
    //
    // Returns an instance of QrbCreditorInformation.
    //
    // Throws QrbException if read fails.
    public function readCredInfo() : QrbCreditorInformation;

    // Reads (optional) additional information.
    //
    // Returns an instance of QrbAdditionalInformation or NULL if there is no additional information.
    public function readAddInfo(array $additionalLanguages) : ?QrbAdditionalInformation;

    // Read recipients.
    // For more details on the checks, see QrbRecipient.
    //
    // qrbDataType:        either QrbDataType::RECIPIENTS or QrbDataType::TEST_RCPNTS
    // amountMandatory:    if true checks that all recipients have an amount
    // createPdf:          if true checks that all recipients have the fields required to create a PDF
    // referenceMandatory: if true checks that all recipients have a reference
    // sendMail:           if true checks that all recipients have an e-mail address
    //
    // Returns a list of QrbRecipient.
    //
    // Throws QrbException if read fails.
    public function readRecipients(QrbDataType $qrbDataType, 
                                   bool        $amountMandatory, 
                                   bool        $createPdf, 
                                   bool        $referenceMandatory, 
                                   bool        $sendMail) : array; // of QrbRecipient

    // Stores the given PDF with the given name.
    //
    // Throws QrbException if store fails.
    public function storeQrBillPdf(string $pdfOutputName, string $pdfOutput) : void;

    
    // Initializes a new run depending on the profile and the given name of the run.
    //
    // runName: name of the run
    // testRun: if true then the output is marked as beeing created by a test run 
    //          (only the last test run is preserved, see deleteOutputOfOldRuns())
    // dryRun:  if true then no output directory is created
    //
    // Throws QrbException if initialization fails somehow.
    public function initializeNewRun(string $runName, bool $testRun, bool $dryRun) : void;

    // Writes the given protocol entries to disk.
    //
    // protocol: array of QrbProtocolEntry
    //
    // Returns a string containing the relative path to the current protocol
    // or NULL in case the protocol has not been stored (empty or dryRun).
    //
    // Throws QrbException if store fails.
    public function writeProtocol(array $protocol) : ?string;

    // Zips the result of the current run and returns a link to the created ZIP file.
    //
    // Returns a string containing the relative path to the created ZIP archive
    //         or NULL if there were no files to zip.
    //
    // Throws QrbException if creating the ZIP archive fails.
    public function zipCurrentRun() : ?string;

    // Deletes output files of old runs.
    public function deleteOutputOfOldRuns() : void;


    // Deletes all the data (for clean up in unit tests).
    public function deleteData() : void;
}

?>
