<?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\Etalon;

use JsonException;
use Sut\Domain\Issue\IssueFactory;

class GetUpdatedPackages
{
    /**
     * @var IssueFactory
     */
    private $issueFactory;

    /**
     * @param IssueFactory $issueFactory
     */
    public function __construct(IssueFactory $issueFactory)
    {
        $this->issueFactory = $issueFactory;
    }

    /**
     * @param string $path
     * @param string $etalonPath
     * @return array
     * @throws JsonException
     */
    public function execute(string $path, string $etalonPath): array
    {
        $packageVersions = $this->getPackageVersions($path);
        $issues = [];
        foreach ($this->getPackageVersions($etalonPath) as $name => $version) {
            if (!isset($packageVersions[$name])) {
                $issues[$name] = $this->issueFactory->createIssue(
                    2003,
                    [$name]
                );
                continue;
            }
            if ($version !== $packageVersions[$name]) {
                $issues[$name] = $this->issueFactory->createIssue(
                    2004,
                    [$name, $version, $packageVersions[$name]]
                );
            }
        }
        return $issues;
    }

    /**
     * @param string $path
     * @return string[]
     * @throws JsonException
     */
    private function getPackageVersions(string $path): array
    {
        $composerLockPath = rtrim($path, '/') . '/' . 'composer.lock';
        if (!file_exists($composerLockPath)) {
            return [];
        }
        $composerLockContent = json_decode(file_get_contents($composerLockPath), true, 512, JSON_THROW_ON_ERROR);
        if (!isset($composerLockContent['packages'])) {
            return [];
        }
        $packageVersions = [];
        foreach ($composerLockContent['packages'] as $package) {
            $packageVersions[$package['name']] = $package['version'];
        }
        if (isset($composerLockContent['packages-dev'])) {
            foreach ($composerLockContent['packages-dev'] as $package) {
                $packageVersions[$package['name']] = $package['version'];
            }
        }
        return $packageVersions;
    }
}
