<?php

declare (strict_types=1);
namespace OCA\News\Vendor\FeedIo;

use DOMDocument;
use DOMElement;
use OCA\News\Vendor\FeedIo\Feed\NodeInterface;
abstract class RuleAbstract
{
    public const NODE_NAME = 'node';
    protected string $nodeName;
    public function __construct(?string $nodeName = null)
    {
        $this->nodeName = $nodeName ?? static::NODE_NAME;
    }
    public function getNodeName(): string
    {
        return $this->nodeName;
    }
    public function getAttributeValue(DOMElement $element, string $name): ?string
    {
        if ($element->hasAttribute($name)) {
            return $element->getAttribute($name);
        }
        return null;
    }
    public function getChildValue(DOMElement $element, string $name, ?string $ns = null): ?string
    {
        if ($ns === null) {
            $list = $element->getElementsByTagName($name);
        } else {
            $list = $element->getElementsByTagNameNS($ns, $name);
        }
        if ($list->length > 0) {
            return $list->item(0)->nodeValue;
        }
        return null;
    }
    public function getChildAttributeValue(DOMElement $element, string $child_name, string $attribute_name, ?string $ns = null): ?string
    {
        if ($ns === null) {
            $list = $element->getElementsByTagName($child_name);
        } else {
            $list = $element->getElementsByTagNameNS($ns, $child_name);
        }
        if ($list->length > 0) {
            return $list->item(0)->getAttribute($attribute_name);
        }
        return null;
    }
    public function apply(DomDocument $document, DOMElement $rootElement, NodeInterface $node): void
    {
        if ($this->hasValue($node)) {
            $this->addElement($document, $rootElement, $node);
        }
    }
    protected function setNonEmptyAttribute(DomElement $element, string $name, ?string $value = null): void
    {
        if (!is_null($value)) {
            $element->setAttribute($name, $value);
        }
    }
    protected function appendNonEmptyChild(DomDocument $document, DOMElement $element, string $name, ?string $value = null): void
    {
        if (!is_null($value)) {
            $element->appendChild($document->createElement($name, $value));
        }
    }
    abstract public function setProperty(NodeInterface $node, DOMElement $element): void;
    abstract protected function hasValue(NodeInterface $node): bool;
    abstract protected function addElement(DomDocument $document, DOMElement $rootElement, NodeInterface $node): void;
}
