<?php

namespace App\Libraries\MyCrawler;

use App\Libraries\CommonLibrary;
use Symfony\Component\DomCrawler\Crawler;

abstract class MyCrawlerLibrary extends CommonLibrary
{
    protected $_mySocket = null;
    protected $_myStorage = null;
    protected function __construct()
    {
        parent::__construct();
    }
    abstract public function execute(): void;
    abstract protected function getMySocket(): mixed;
    abstract protected function getMyStorage(): mixed;
    final protected function getSelector(string $content, string $tag): Crawler
    {
        $crawler = new Crawler($content);
        if ($this->getDebug()) {
            log_message("debug", sprintf(
                "\n---------%s----------\ntag:%s\n%s\n-------------------\n",
                __FUNCTION__,
                $tag,
                $content
            ));
            exit;
        }
        return $crawler->filter($tag);
    }

    protected function save(string $url, string $mediaType, int $file_sequence): mixed
    {
        $data = $this->getMySocket()->download($url);
        $this->getMyStorage()->setOriginName($this->getMySocket()->getFileName());
        $this->getMyStorage()->setOriginContent($data);
        $this->getMyStorage()->setOriginType($mediaType);
        $this->getMyStorage()->setOriginSequence($file_sequence);
        return $this->getMyStorage()->save();
    }

    final protected function download(string $mediaType, Crawler $selector, array $options, array $myStorageLibrarys = []): array
    {
        $nodes = [];
        $selector->filter($options["tag"])->each(
            function (Crawler $node) use (&$options, &$nodes): void {
                log_message("debug", sprintf(
                    "getNode->%s[%s]",
                    $options["tag"],
                    $node->attr($options['attr'])
                ));
                $nodes[] = $node;
            }
        );
        $file_sequence = 1;
        foreach ($nodes as $node) {
            try {
                $myStorageLibrarys[] = $this->save($node->attr($options["attr"]), $mediaType, $file_sequence);
                $file_sequence++;
                log_message("notice", __FUNCTION__ . " OriginType->{$mediaType} 작업 완료");
            } catch (\Exception $e) {
                log_message("warning", sprintf(
                    "\n---%s,OriginType->%s 오류---\n%s\n-----------------------------------------\n",
                    __FUNCTION__,
                    $mediaType,
                    $e->getMessage()
                ));
            }
        }
        return $myStorageLibrarys;
    }
}
