<?php
/**
 * Copyright 2022 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.
 */
namespace Sut\Domain\Compatibility\Analyzers\Db;

use Magento\Mray\MagentoApiIndex\Api\DbSchemaInfo;
use Sut\Domain\Compatibility\Analyzers\AnalyzerInterface;
use Sut\Domain\Issue\IssueFactory;
use Sut\Domain\MRay\DTO\Module;

class IndexAnalyzer implements AnalyzerInterface
{
    private const USAGES = [
        'added-index-to-core-table',
        'extended-core-table-index'
    ];

    private const ISSUE_CODES = [
        'Added index conflicts with core index referenceId' => 7005,
        'Extended core table index does not exist' => 7006
    ];

    /**
     * @var DbSchemaInfo
     */
    private $dbSchemaInfo;

    /**
     * @var IssueFactory
     */
    private $issueFactory;

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

    /**
     * @inheritdoc
     */
    public function analyze(Module\Dependency $dependency, Module\DependencyUsage $usage, string $version): array
    {
        if ($dependency->getType() !== 'db') {
            return [];
        }

        if (!in_array($usage->getType(), self::USAGES)) {
            return [];
        }

        $tableIndexName = explode('.', $dependency->getRealName());
        if (count($tableIndexName) !== 2) {
            return [];
        }

        $tableName = reset($tableIndexName);
        $indexName = end($tableIndexName);

        if ($usage->getType() === 'added-index-to-core-table'
            && $this->dbSchemaInfo->getIndex($tableName, $indexName, $version) !== null
        ) {
            return [$this->issueFactory->createIssue(
                self::ISSUE_CODES['Added index conflicts with core index referenceId'],
                [$dependency->getRealName(), $version],
                $usage->getPosition(),
                $usage->getFile()
            )];
        }

        if ($usage->getType() === 'extended-core-table-index'
            && $this->dbSchemaInfo->getIndex($tableName, $indexName, $version) === null
        ) {
            return [$this->issueFactory->createIssue(
                self::ISSUE_CODES['Extended core table index does not exist'],
                [$dependency->getRealName(), $version],
                $usage->getPosition(),
                $usage->getFile()
            )];
        }

        return [];
    }
}
