<?php
/**
 * Webkul Software.
 *
 * @category  Webkul
 * @package   Webkul_AdvanceSeoManager
 * @author    Webkul
 * @copyright Copyright (c) Webkul Software Private Limited (https://webkul.com)
 * @license   https://store.webkul.com/license.html
 */

namespace Webkul\AdvanceSeoManager\Model;

use Magento\Framework\DataObject as MagentoDataObject;
use Magento\Framework\App\ObjectManager;
use Magento\Sitemap\Model\ItemProvider\ItemProviderInterface;
use Magento\Sitemap\Model\ItemProvider\Category;
use Magento\Sitemap\Model\ItemProvider\Product;
use Magento\Sitemap\Model\ItemProvider\CmsPage;
use Magento\Sitemap\Model\ResourceModel\Catalog\CategoryFactory;
use Magento\Sitemap\Model\SitemapConfigReaderInterface;
use Magento\Config\Model\Config\Reader\Source\Deployed\DocumentRoot;

class Sitemap extends \Magento\Sitemap\Model\Sitemap
{
    /**
     * Initialize sitemap items
     *
     * @return void
     */
    protected $categoryClass;

    protected $productClass;

    protected $directory;

    protected $documentRoot;

    protected $filesystem;

    public function __construct(
        \Magento\Framework\Model\Context $context,
        \Magento\Framework\Registry $registry,
        \Magento\Framework\Escaper $escaper,
        \Magento\Sitemap\Helper\Data $sitemapData,
        \Magento\Framework\Filesystem $filesystem,
        \Magento\Sitemap\Model\ResourceModel\Catalog\CategoryFactory $categoryFactory,
        \Magento\Sitemap\Model\ResourceModel\Catalog\ProductFactory $productFactory,
        \Magento\Sitemap\Model\ResourceModel\Cms\PageFactory $cmsFactory,
        \Magento\Framework\Stdlib\DateTime\DateTime $modelDate,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Framework\App\RequestInterface $request,
        \Magento\Framework\Stdlib\DateTime $dateTime,
        Category $categoryClass,
        Product $productClass,
        CmsPage $cmsPageClass,
        DocumentRoot $documentRoot,
        \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
        \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
        array $data = [],
        ItemProviderInterface $itemProvider = null,
        SitemapConfigReaderInterface $configReader = null,
        \Magento\Sitemap\Model\SitemapItemInterfaceFactory $sitemapItemFactory = null
    ) {
        $this->categoryClass=$categoryClass;
        $this->productClass=$productClass;
        $this->cmsPageClass=$cmsPageClass;
        $this->documentRoot=$documentRoot;
        $this->filesystem=$filesystem;
        $directory = $this->filesystem->getDirectoryWrite($this->documentRoot->getPath());
        parent::__construct(
            $context,
            $registry,
            $escaper,
            $sitemapData,
            $filesystem,
            $categoryFactory,
            $productFactory,
            $cmsFactory,
            $modelDate,
            $storeManager,
            $request,
            $dateTime,
            $resource,
            $resourceCollection,
            $data,
            $documentRoot,
            $itemProvider,
            $configReader,
            $sitemapItemFactory
        );
    }

    protected function _initSitemapItems()
    {
        /**
         * @var $helper \Magento\Sitemap\Helper\Data
        */
        $siteMapType = $this->_request->getParam("sitemap_type");
        if ($siteMapType == "category") {
            $this->_sitemapItems[] = $this->categoryClass->getItems($this->getStoreId());
        } elseif ($siteMapType == "product") {
            $this->_sitemapItems[] = $this->productClass->getItems($this->getStoreId());
        } else {
            $this->_sitemapItems[] = $this->categoryClass->getItems($this->getStoreId());
            $this->_sitemapItems[] = $this->productClass->getItems($this->getStoreId());
        }
        $this->_sitemapItems[] = $this->cmsPageClass->getItems($this->getStoreId());

        $this->_tags = [
            self::TYPE_INDEX => [
                self::OPEN_TAG_KEY => '<?xml version="1.0" encoding="UTF-8"?>' .
                PHP_EOL .
                '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' .
                PHP_EOL,
                self::CLOSE_TAG_KEY => '</sitemapindex>',
            ],
            self::TYPE_URL => [
                self::OPEN_TAG_KEY => '<?xml version="1.0" encoding="UTF-8"?>' .
                PHP_EOL .
                '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"' .
                ' xmlns:content="http://www.google.com/schemas/sitemap-content/1.0"' .
                ' xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">' .
                PHP_EOL,
                self::CLOSE_TAG_KEY => '</urlset>',
            ],
        ];
    }

    /**
     * Generate XML file
     *
     * @see http://www.sitemaps.org/protocol.html
     *
     * @return $this
     */
    public function generateXml()
    {
        $this->_initSitemapItems();

        /** @var $item SitemapItemInterface */
        foreach ($this->_sitemapItems as $siteItem) {
            foreach ($siteItem as $item) {
                $xml = $this->_getSitemapRow(
                    $item->getUrl(),
                    $item->getUpdatedAt(),
                    $item->getChangeFrequency(),
                    $item->getPriority(),
                    $item->getImages()
                );
    
                if ($this->_isSplitRequired($xml) && $this->_sitemapIncrement > 0) {
                    $this->_finalizeSitemap();
                }
    
                if (!$this->_fileSize) {
                    $this->_createSitemap();
                }
    
                $this->_writeSitemapRow($xml);
                // Increase counters
                $this->_lineCount++;
                $this->_fileSize += strlen($xml);
            }
        }

        $this->_finalizeSitemap();

        if ($this->_sitemapIncrement == 1) {
            // In case when only one increment file was created use it as default sitemap
            $path = rtrim(
                $this->getSitemapPath(),
                '/'
            ) . '/' . $this->_getCurrentSitemapFilename(
                $this->_sitemapIncrement
            );
            $destination = rtrim($this->getSitemapPath(), '/') . '/' . $this->getSitemapFilename();

            $this->_directory->renameFile($path, $destination);
        } else {
            // Otherwise create index file with list of generated sitemaps
            $this->_createSitemapIndex();
        }

        $this->setSitemapTime($this->_dateModel->gmtDate('Y-m-d H:i:s'));
        $this->save();

        return $this;
    }
}
