<?php

namespace CfdiUtils\CadenaOrigen;

use CfdiUtils\CfdiVersion;

/**
 * The class CadenaOrigenLocations create the cadena de origen by transforming the XML contents
 * using the XSLT utilities provided by SAT.
 *
 * This class is a helps override or set the location of the xslt resource.
 *
 * @deprecated :3.0.0 it does not have any replacement
 * @codeCoverageIgnore
 */
class CadenaOrigenLocations
{
    /**
     * Private array containing urls for xslt versions
     * @var string[]
     */
    private $xsltLocations = [
        '3.2' => CfdiDefaultLocations::XSLT_32,
        '3.3' => CfdiDefaultLocations::XSLT_33,
        '4.0' => CfdiDefaultLocations::XSLT_40,
    ];

    /**
     * Return the registered location of the xslt file to perform the xml transformation
     * depending on the cfdi version. This value can be changed using setXsltLocation
     *
     * @see setXsltLocation
     * @param string $version
     * @return string
     */
    public function getXsltLocation(string $version): string
    {
        if (array_key_exists($version, $this->xsltLocations)) {
            return $this->xsltLocations[$version];
        }
        return '';
    }

    /**
     * Override the default location of the xslt for an specified version
     *
     * @param string $version
     * @param string $location
     */
    public function setXsltLocation(string $version, string $location)
    {
        $this->xsltLocations[$version] = $location;
    }

    /**
     * Return an array of the registered locations using version as key and location as value
     *
     * @return string[]
     */
    public function getXsltLocations(): array
    {
        return $this->xsltLocations;
    }

    public function getXsltLocationFromXml(string $cfdiContent): string
    {
        $cfdiVersion = (new CfdiVersion())->getFromXmlString($cfdiContent);
        $xsltLocation = $this->getXsltLocation($cfdiVersion);
        if ('' === $xsltLocation) {
            throw new \RuntimeException('Cannot get a xslt location from the document');
        }
        return $xsltLocation;
    }

    /**
     * Perform the xslt transformation if the xml contents to create the "Cadena de origen"
     * for a "Comprobante fiscal digital por internet (cfdi)"
     *
     * This method will search for the registered xslt location the xsltLocation argument is empty
     *
     * All errors generated by the process will create a RuntimeException
     *
     * @param string $cfdiContent
     * @return string
     * @throws \UnexpectedValueException if the cfdi content is empty
     * @throws \RuntimeException on procedural errors
     */
    public function build(string $cfdiContent): string
    {
        $xsltLocation = $this->getXsltLocationFromXml($cfdiContent);
        $builder = new DOMBuilder();
        return $builder->build($cfdiContent, $xsltLocation);
    }
}
