<?php
declare(strict_types=1);

namespace PpPhp\Core\Platform\Workflow\Bpmn;

final class BpmnParser
{
    public function parse(string $xml): BpmnModel
    {
        $document = new \DOMDocument();
        $document->loadXML($xml);

        $xpath = new \DOMXPath($document);
        $xpath->registerNamespace('bpmn', 'http://www.omg.org/spec/BPMN/20100524/MODEL');

        $process = $xpath->query('//*[local-name()="process"]')->item(0);
        if (!$process instanceof \DOMElement) {
            throw new \RuntimeException('BPMN process element not found.');
        }

        $processId = $process->getAttribute('id') ?: 'imported_process';
        $name = $process->getAttribute('name') ?: $processId;

        $elements = [];
        $flows = [];

        foreach ($process->childNodes as $child) {
            if (!$child instanceof \DOMElement) {
                continue;
            }

            $local = $child->localName;
            $id = $child->getAttribute('id');
            if ($id === '') {
                continue;
            }

            if ($local === 'sequenceFlow') {
                $flows[] = BpmnFlow::create(
                    $id,
                    $child->getAttribute('sourceRef'),
                    $child->getAttribute('targetRef'),
                    $child->getAttribute('name')
                )->toArray();
                continue;
            }

            $supported = ['startEvent', 'endEvent', 'task', 'userTask', 'serviceTask', 'exclusiveGateway', 'parallelGateway', 'inclusiveGateway', 'intermediateCatchEvent'];
            if (in_array($local, $supported, true)) {
                $elements[] = BpmnElement::create($id, $local, $child->getAttribute('name'), [
                    'rawType' => $local,
                ])->toArray();
            }
        }

        return BpmnModel::create($processId, $name, $elements, $flows, 'import');
    }
}
