<?php

namespace Webkul\DamBundle\Connector\Reader\Import;

use Webkul\DamBundle\Services\DamServices;
use Ijanki\Bundle\FtpBundle\Exception\FtpException;
use Webkul\DamBundle\Listener\ClassDefinationForCompatibility;

$versionCompatiblility = new ClassDefinationForCompatibility();
$versionCompatiblility->createClassAliases();
/**
 * Ftp reader
 *
 * @author    Aman Srivastava <aman.srivastava462@webkul.com>
 * @copyright 2019 Webkul Software Pvt. Ltd. (https://webkul.com)
 */
class AssetFtpReader implements
        \ItemReaderInterface,
        \InitializableInterface,
        \StepExecutionAwareInterface
{
    /** @var StepExecution */
    protected $stepExecution;

    /** @var DamServices */
    protected $damService;

    /** @var $damData */
    protected $damData = [];

    /** @var $filePath */
    protected $filePath;

    /** @var $dirAsset */
    protected $dirAsset = [];

    /** @var $assetCode */
    protected $assetCode;

    /** @var $description */
    protected $description = null;

    /** @var $damTags */
    protected $damTags = [];

    /** @var $starred */
    protected $starred = false;

    /** @var $title */
    protected $title = null;

    /** @var $alt */
    protected $alt = null;

    /** @var $damCategories */
    protected $damCategories = [];

    /** @var $validExtension */
    protected $validExtensions = [];

    /** @var  FtpException*/
    protected $ftpConnection = null;

    /** @var ArrayConverterInterface */
    protected $converter;


    /**
     * @param ArrayConverterInterface $converter
     * @param DamServices             $DamServices
     * @param array                   $options
     */
    public function __construct(
        \ArrayConverterInterface $converter,
        DamServices $damService
    ) {
        $this->converter = $converter;
        $this->damService = $damService;
    }

    /**
     * Flat Format of Dam Data
     * [
     *      "code"  => "code",
     *      "media" => [
     *                      "/tmp/dummy1.jpg",
     *                      "/tmp/dummy2.jpg",
     *                  ]
     *      "alt"   => "alt",
     *      "created_at" => "created_date",
     *      "descriptions" => "descriptions"
     *      "tags"  => tag1 & tag2 & tag3 & tag4,
     *      "categories" => category1 & category2 & category3 & category4,
     * ]
     */

    /**
     * Intialize data in @var item
     */
    public function initialize()
    {
        $jobParameters = $this->stepExecution->getJobParameters();
        $hostName = $jobParameters->has('hostname') ? $jobParameters->get('hostname') : null;
        $username = $jobParameters->has('username') ? $jobParameters->get('username') : null;
        $password = $jobParameters->has('password') ? $jobParameters->get('password') : null;
        $this->description = $jobParameters->has('description') ? $jobParameters->get('description') : null;
        $this->damTags = $jobParameters->has('dam_tags') ? $jobParameters->get('dam_tags') : null;
        $this->starred = $jobParameters->has('starred') ? $jobParameters->get('starred') : null;
        $this->title = $jobParameters->has('title') ? $jobParameters->get('title') : null;
        $this->alt = $jobParameters->has('alt') ? $jobParameters->get('alt') : null;
        $this->damCategories = $jobParameters->has('dam_categories') ? $jobParameters->get('dam_categories') : null;
        $this->filePath = $jobParameters->has('filePath') ? $jobParameters->get('filePath') : null;
        $this->validExtensions = $jobParameters->has('extension') ? $jobParameters->get('extension') : null;
        $this->ftpConnection = $this->damService->connectToFtp($hostName, $username, $password, $this->filePath);

        if (!$this->ftpConnection) {
            throw new \DataArrayConversionException('Credentials are not valid');
        }
       
        $files_single_asset = $jobParameters->has('files_single_asset') ? $jobParameters->get('files_single_asset') : null;
        $dir_asset_check = $jobParameters->has('dir_asset_check') ? $jobParameters->get('dir_asset_check') : null;
        $only_asset_check = $jobParameters->has('only_asset_check') ? $jobParameters->get('only_asset_check') : null;
        
        switch (true) {
            case $files_single_asset:
                $this->damData = $this->importFileAsSingleAsset();
                break;

            case $dir_asset_check:
                $this->dirAsset = $jobParameters->has('dir_asset') ? $jobParameters->get('dir_asset') : null;
                $this->damData = $this->importDirAsAsset();
                break;

            case $only_asset_check:
                $this->assetCode = $jobParameters->has('only_asset') ? $jobParameters->get('only_asset') : null;
                $this->damData = $this->importFileInAsset();
                break;
                
            default:
                $this->stepExecution->addWarning("Please select any of the type in which you want to Import", [], new \DataInvalidItem([]));
        }
    }
    /**
     * {@inheritdoc}
     */
    public function read()
    {
        $item = null;
        if ($data = current($this->damData)) {
            $item = [];

            next($this->damData);

            try {
                $item = $this->converter->convert($data, $this->getArrayConverterOptions());
                $this->stepExecution->incrementSummaryInfo('read', 1);
            } catch (\DataArrayConversionException $e) {
                $this->skipItemFromConversionException($data, $e);
            }
        }

        return $item;
    }

    /**
     * {@inheritdoc}
     */
    public function setStepExecution(\StepExecution $stepExecution)
    {
        $this->stepExecution = $stepExecution;
    }

    /**
     * Returns the options for array converter. It can be overridden in the sub classes.
     *
     * @return array
     */
    protected function getArrayConverterOptions()
    {
        return [];
    }

    /**
     * @param array                        $item
     * @param DataArrayConversionException $exception
     *
     * @throws \InvalidItemException
     * @throws InvalidItemFromViolationsException
     */
    protected function skipItemFromConversionException(array $item, \DataArrayConversionException $exception)
    {
        if (null !== $this->stepExecution) {
            $this->stepExecution->incrementSummaryInfo('skip');
        }

        if (null !== $exception->getViolations()) {
            throw new \InvalidItemFromViolationsException(
                $exception->getViolations(),
                new \FileInvalidItem($item, ($this->stepExecution->getSummaryInfo('item_position'))),
                [],
                0,
                $exception
            );
        }

        $invalidItem = new \FileInvalidItem(
            $item,
            ($this->stepExecution->getSummaryInfo('item_position'))
        );

        throw new \InvalidItemException($exception->getMessage(), $invalidItem, [], 0, $exception);
    }
    
    /**
     * @param array
     * @param Data
     */
    public function importFileAsSingleAsset()
    {
        $items = [];

        $fileLists = $this->ftpConnection->nlist($this->filePath);

        if ($fileLists) {
            foreach ($fileLists as $key => $fileList) {
                $fileInfo = pathinfo($fileList);
                $item = null;
                $validExtension =  ["jpg","jpeg", "png", "bmp", "gif", "tiff", "pdf", "doc", "svg"];

                if (!empty($this->validExtensions)) {
                    $validExtension = $this->validExtensions;
                }

                if (isset($fileInfo['extension']) && in_array($fileInfo['extension'], $validExtension)) {
                    $item =  [
                        "code" => isset($fileInfo['filename']) ? $this->damService->convertToCode($fileInfo['filename']) : uniqid(),
                        "media" => [ $this->damService->StoreIntoTemp($this->ftpConnection, $fileList)],
                        "starred" => $this->starred,
                        "title" => $this->title ,
                        "alt" => $this->alt ,
                        "categories" => !empty($this->damCategories) ? implode(" & ", $this->damCategories) : null,
                        "description" => $this->description,
                        "tags" =>  !empty($this->damTags) ? implode(" & ", $this->damTags) : null
                    ];
                }
                
                if ($item) {
                    $items[] = $item;
                }
            }
        }
        
        return $items;
    }

    /**
     * @param array
     * @param Data
     */
    public function importDirAsAsset()
    {
        $items = [];

        foreach ($this->dirAsset as $dAsset) {
            $item = null;
            $basePath = rtrim($this->filePath, '/') . '/' . $dAsset;
            
            $fileLists = $this->ftpConnection->nlist($basePath);

            if (!empty($fileLists)) {
                $medias = [];
                foreach ($fileLists as $key => $fileList) {
                    $fileInfo = pathinfo($fileList);
                    $validExtension =  ["jpg", "jpeg", "png", "bmp", "gif", "tiff", "pdf", "doc", "svg"];

                    if (!empty($this->validExtensions)) {
                        $validExtension = $this->validExtensions;
                    }

                    if (isset($fileInfo['extension']) && in_array($fileInfo['extension'], $validExtension)) {
                        $medias[] = $this->damService->StoreIntoTemp($this->ftpConnection, $fileList);
                    }
                }

                if (!empty($medias)) {
                    $item = [
                        "code" => $this->damService->convertToCode($dAsset),
                        "media" => $medias,
                        "starred" => $this->starred,
                        "title" => $this->title ,
                        "alt" => $this->alt ,
                        "categories" => implode(" & ", $this->damCategories),
                        "description" => $this->description,
                        "tags" =>  implode(" & ", $this->damTags)
                    ];
                }
            }

            if ($item) {
                $items[] = $item;
            }
        }
        
        return $items;
    }

    /**
     * @param array
     * @param Data
     */
    public function importFileInAsset()
    {
        $items = [];
        if ($this->assetCode) {
            $allCodes = $this->damService->getAllAssetCodes();

            if (in_array($this->assetCode, $allCodes)) {
                $fileLists = $this->ftpConnection->nlist($this->filePath);
    
                $medias = [];
    
                if (!empty($fileLists)) {
                    foreach ($fileLists as $key => $fileList) {
                        $fileInfo = pathinfo($fileList);
                        $validExtension =  ["jpg", "jpeg", "png", "bmp", "gif", "tiff", "pdf", "doc", "svg"];
    
                        if (!empty($this->validExtensions)) {
                            $validExtension = $this->validExtensions;
                        }
    
                        if (isset($fileInfo['extension']) && in_array($fileInfo['extension'], $validExtension)) {
                            $medias[] = $this->damService->StoreIntoTemp($this->ftpConnection, $fileList);
                        }
                    }
                }
    
                if (!empty($medias)) {
                    $items[] = [
                        "code" => $this->assetCode,
                        "media" => $medias,
                        "starred" => $this->starred,
                        "title" => $this->title ,
                        "alt" => $this->alt ,
                        "categories" => implode(" & ", $this->damCategories),
                        "description" => $this->description,
                        "tags" =>  implode(" & ", $this->damTags)
                    ];
                }
            }
        }

        return $items;
    }
}
