<?php

namespace App\Services\Certification;

use App\Services\WorkflowDictionary;

final class WorkflowCertification
extends BaseCertification
{
    public static function module(): string
    {
        return 'Workflow';
    }

    public static function certify(): array
    {
        $warnings = [];
        $errors   = [];
        $meta     = [];

        /*
        ----------------------------------------------------
        WorkflowDictionary
        ----------------------------------------------------
        */

        if (!class_exists(WorkflowDictionary::class)) {

            $errors[] =
                'WorkflowDictionary missing';

            return self::fail($errors);

        }

        /*
        ----------------------------------------------------
        Canonical stages
        ----------------------------------------------------
        */

        $stages =
            WorkflowDictionary::STAGES ?? [];

        $statuses =
            WorkflowDictionary::STATUS ?? [];

        $meta['stages'] =
            count($stages);

        $meta['statuses'] =
            count($statuses);

        if (count($stages) < 6) {

            $warnings[] =
                'Very small stage dictionary';

        }

        if (count($statuses) < 6) {

            $warnings[] =
                'Very small status dictionary';

        }

        /*
        ----------------------------------------------------
        Mandatory stages
        ----------------------------------------------------
        */

        foreach (

            [

                'submission',

                'review',

                'decision',

                'production',

                'published'

            ]

            as $required

        ) {

            if (

                !in_array(
                    $required,
                    $stages,
                    true
                )

            ) {

                $errors[] =
                    'Missing stage: ' .
                    $required;

            }

        }

        /*
        ----------------------------------------------------
        Score
        ----------------------------------------------------
        */

        $score = 100;

        $score -=
            count($warnings) * 5;

        $score -=
            count($errors) * 20;

        $score =
            max(
                0,
                $score
            );

        if (!empty($errors)) {

            return self::fail(

                $errors,

                $warnings,

                $meta

            );

        }

        if (!empty($warnings)) {

            return self::warning(

                $score,

                $warnings,

                $meta

            );

        }

        return self::pass($meta);
    }
}
