<?php

namespace Acms\Services\StaticExport\Generator;

use Acms\Services\StaticExport\Contracts\Generator;
use Acms\Services\Facades\Storage;
use SQL;
use DB;
use ACMS_Filter;

class CategoryGenerator extends Generator
{
    /**
     * @var int
     */
    protected $numberOfCategories;

    protected function getName()
    {
        return 'カテゴリートップの書き出し';
    }

    protected function getTasks()
    {
        return $this->numberOfCategories * 3;
    }

    /**
     * @return void
     */
    protected function main()
    {
        $categories = $this->getCategories();
        $this->numberOfCategories = count($categories);

        $this->logger->start($this->getName(), $this->getTasks());

        foreach ($categories as $category) {
            $cid = $category['category_id'];
            $info = array(
                'bid' => BID,
                'cid' => $cid,
            );
            
            try {
                $url = acmsLink($info);
                $this->request($url, array($info, 'index.html'));
                $this->request($url . 'rss2.xml', array($info, 'rss2.xml'));
                $this->request($url . 'sitemap.xml', array($info, 'sitemap.xml'));
            } catch ( \Exception $e ) {
                $this->logger->error($e->getMessage(), $url);
            }
        }
    }

    /**
     * @param string $data
     * @param string $code
     * @param object $info
     * @return void
     */
    protected function callback($data, $code, $info)
    {
        if ( $this->logger ) {
            $this->logger->processing();
        }
        if ( empty($data) || $code != '200' ) {
            $this->logger->error('データの取得に失敗しました。', acmsLink($info[0]), $code);
            return;
        }
        $destination = $this->destination->getDestinationPath() . $this->destination->getBlogCode();
        $blog_url = acmsLink(array('bid'=>BID));
        $url = acmsLink($info[0]);
        $dir = substr($url, strlen($blog_url));

        try {
            Storage::makeDirectory($destination . $dir);
            Storage::put($destination . $dir . $info[1], $data);
        } catch ( \Exception $e ) {
            $this->logger->error('データの書き込みに失敗しました。', $destination . $dir . 'index.html');
        }
    }

    /**
     * @return mixed
     */
    private function getCategories()
    {
        $SQL = SQL::newSelect('category');
        $SQL->addSelect('category_id');
        $SQL->addLeftJoin('blog', 'blog_id', 'category_blog_id');
        ACMS_Filter::blogTree($SQL, BID, 'ancestor-or-self');
        ACMS_Filter::categoryStatus($SQL);

        $Where  = SQL::newWhere();
        $Where->addWhereOpr('category_blog_id', BID, '=', 'OR');
        $Where->addWhereOpr('category_scope', 'global', '=', 'OR');
        $SQL->addWhere($Where);

        return DB::query($SQL->get(dsn()), 'all');
    }
}