<?php
/**
 * Copyright 2020 Adobe
 * All Rights Reserved.
 *
 * NOTICE: Adobe permits you to use, modify, and distribute this file in
 * accordance with the terms of the Adobe license agreement accompanying
 * it.
 */
declare(strict_types=1);

namespace Sut\Domain\Compatibility\Output\Html;

use JsonException;
use Sut\Domain\Compatibility\Data\AnalysisResult;

class Render
{
    /**
     * @param AnalysisResult $analysisResult
     * @param string $documentationLink
     * @return string
     */
    public function execute(AnalysisResult $analysisResult, string $documentationLink): string
    {
        ob_start();

        // phpcs:ignore
        include 'template.phtml';

        return ob_get_clean();
    }

    /**
     * @param AnalysisResult $analysisResult
     * @return string
     * @throws JsonException
     */
    private function getPieChartColumns(AnalysisResult $analysisResult): string
    {
        $withCriticals = 0;
        $withErrors = 0;
        $withWarnings = 0;
        $withoutIssues = 0;
        foreach ($analysisResult->getModules() as $module) {
            if (!empty($module->getSummary()->getCriticals())) {
                $withCriticals++;
                continue;
            }
            if (!empty($module->getSummary()->getErrors())) {
                $withErrors++;
                continue;
            }
            if (!empty($module->getSummary()->getWarnings())) {
                $withWarnings++;
                continue;
            }
            $withoutIssues++;
        }
        return json_encode([
            ['Modules without issues', $withoutIssues],
            ['Modules with warnings', $withWarnings],
            ['Modules with errors', $withErrors],
            ['Modules with critical issues', $withCriticals],
        ], JSON_THROW_ON_ERROR);
    }

    /**
     * @param AnalysisResult $analysisResult
     * @return string
     * @throws JsonException
     */
    private function getFilesPieChartColumns(AnalysisResult $analysisResult): string
    {
        $withCriticals = 0;
        $withErrors = 0;
        $withWarnings = 0;
        foreach ($analysisResult->getFiles() as $file) {
            if (!empty($file->getSummary()->getCriticals())) {
                $withCriticals++;
                continue;
            }
            if (!empty($file->getSummary()->getErrors())) {
                $withErrors++;
                continue;
            }
            $withWarnings++;
        }
        return json_encode([
            ['Files without issues', $analysisResult->getTotalNumberOfFiles() - count($analysisResult->getFiles())],
            ['Files with warnings', $withWarnings],
            ['Files with errors', $withErrors],
            ['Files with critical issues', $withCriticals],
        ], JSON_THROW_ON_ERROR);
    }

    /**
     * @param AnalysisResult $analysisResult
     * @return string
     * @throws JsonException
     */
    private function getBarChartColumns(AnalysisResult $analysisResult): string
    {
        $modulesRow = ['x'];
        $warnings = ['warning'];
        $errors = ['error'];
        $criticals = ['critical'];

        $modules = $analysisResult->getModules();

        usort($modules, function ($a, $b) {
            if ($a->getIssues() === $b->getIssues()) {
                return 0;
            }
            return ($a->getIssues() > $b->getIssues()) ? -1 : 1;
        });

        foreach (array_slice($modules, 0, 10) as $module) {
            $modulesRow[] = $module->getModule()->getName();
            $criticals[] = count($module->getSummary()->getCriticals());
            $errors[] = count($module->getSummary()->getErrors());
            $warnings[] = count($module->getSummary()->getWarnings());
        }

        return json_encode([
            $modulesRow,
            $warnings,
            $errors,
            $criticals
        ], JSON_THROW_ON_ERROR);
    }

    /**
     * @param AnalysisResult $analysisResult
     * @param int|null $minIssueLevel
     * @return string
     * @throws JsonException
     */
    private function getBubbleChartData(
        AnalysisResult $analysisResult,
        int $minIssueLevel = 0
    ): string {
        $vendoredModules = [];
        foreach ($analysisResult->getModules() as $module) {
            $parts = explode('_', $module->getModule()->getName());
            $vendoredModules[$parts[0]][$parts[1]] = [
                'size' => $module->getTotalNumberOfFiles(),
                'issues' => count($module->getFilteredIssues($minIssueLevel)),
            ];
        }

        $forJSON = [
            'name' => 'root',
            'children' => []
        ];
        foreach ($vendoredModules as $vendorName => $modules) {
            $vendor = [
                'name' => $vendorName,
                'children' => []
            ];
            foreach ($modules as $moduleName => $values) {
                $vendor['children'][] = [
                    'name' => $moduleName,
                    'size' => $values['size'],
                    'issues' => $values['issues'],
                ];
            }
            $forJSON['children'][] = $vendor;
        }

        return json_encode($forJSON, JSON_THROW_ON_ERROR);
    }

    /**
     * @param AnalysisResult $analysisResult
     * @param int $minIssueLevel
     * @return int
     */
    private function getMaxIssues(AnalysisResult $analysisResult, int $minIssueLevel = 0): int
    {
        $maxIssues = 0;
        foreach ($analysisResult->getModules() as $module) {
            $issuesCount = count($module->getFilteredIssues($minIssueLevel));
            if ($issuesCount > $maxIssues) {
                $maxIssues = $issuesCount;
            }
        }
        return $maxIssues;
    }
}
