<?php

namespace Ignite\Core\Database\Seeders\Strategy;

use Ignite\Core\Contracts\Database\SeederStrategy;
use SplFileObject;

class Csv extends AbstractStrategy implements SeederStrategy
{
    /** @var bool */
    protected $hasHeaders;

    /** @var array */
    protected $options;

    /**
     * Json strategy constructor.
     *
     * @param string $filepath
     * @param bool   $headers
     * @param array  $options
     */
    public function __construct($filepath, $headers = false, $options = array())
    {
        parent::__construct($filepath);
        $this->hasHeaders = $headers;
        $this->setOptions($options);
    }

    /**
     * Run the seeder using this strategy.
     *
     * @return \Illuminate\Support\Collection
     */
    public function run()
    {
        $data = [];
        $headers = [];

        $filepath = $this->getFilepath();
        $file = $this->getFileObject($filepath);

        while ($current = $file->fgetcsv()) {
            if ($this->hasHeaders && empty($headers)) {
                $headers = $current;
                continue;
            }
            if ($this->hasHeaders) {
                $data[] = array_combine($headers, $current);
            } else {
                $data[] = $current;
            }
        }

        return collect($data);
    }

    /**
     * Get the file as an object.
     *
     * @param  string $filepath
     * @return SplFileObject
     */
    protected function getFileObject($filepath)
    {
        $file = new SplFileObject($filepath, 'r');
        $file->setFlags(SplFileObject::READ_CSV | SplFileObject::SKIP_EMPTY | SplFileObject::DROP_NEW_LINE);
        $file->setCsvControl(
            $this->options['delimiter'],
            $this->options['enclosure'],
            $this->options['escape']
        );

        return $file;
    }

    /**
     * Set the CSV control options.
     *
     * @param  array $options
     * @return $this
     */
    protected function setOptions($options)
    {
        if (! isset($options['delimiter']) || empty($options['delimiter'])) {
            $options['delimiter'] = ",";
        }

        if (! isset($options['enclosure']) || empty($options['enclosure'])) {
            $options['enclosure'] = "\"";
        }

        if (! isset($options['escape']) || empty($options['escape'])) {
            $options['escape'] = "\\";
        }

        $this->options = $options;

        return $this;
    }
}
