<?php namespace Jenssegers\Mongodb\Schema;

use Illuminate\Database\Connection;

class Blueprint extends \Illuminate\Database\Schema\Blueprint
{
    /**
     * The MongoConnection object for this blueprint.
     *
     * @var MongoConnection
     */
    protected $connection;

    /**
     * The MongoCollection object for this blueprint.
     *
     * @var MongoCollection
     */
    protected $collection;

    /**
     * Fluent columns.
     *
     * @var array
     */
    protected $columns = [];

    /**
     * @inheritdoc
     */
    public function __construct(Connection $connection, $collection)
    {
        $this->connection = $connection;

        $this->collection = $connection->getCollection($collection);
    }

    /**
     * @inheritdoc
     */
    public function index($columns = null, $name = null, $algorithm = null, $options = [])
    {
        $columns = $this->fluent($columns);

        // Columns are passed as a default array.
        if (is_array($columns) && is_int(key($columns))) {
            // Transform the columns to the required array format.
            $transform = [];

            foreach ($columns as $column) {
                $transform[$column] = 1;
            }

            $columns = $transform;
        }

        $this->collection->createIndex($columns, $options);

        return $this;
    }

    /**
     * @inheritdoc
     */
    public function primary($columns = null, $name = null, $algorithm = null, $options = [])
    {
        return $this->unique($columns, $options);
    }

    /**
     * @inheritdoc
     */
    public function dropIndex($columns = null)
    {
        $columns = $this->fluent($columns);

        // Columns are passed as a default array.
        if (is_array($columns) && is_int(key($columns))) {
            // Transform the columns to the required array format.
            $transform = [];

            foreach ($columns as $column) {
                $transform[$column] = $column.'_1';
            }

            $columns = $transform;
        }

        foreach ($columns as $column) {
            $this->collection->dropIndex($column);
        }

        return $this;
    }

    /**
     * @inheritdoc
     */
    public function unique($columns = null, $name = null, $algorithm = null, $options = [])
    {
        $columns = $this->fluent($columns);

        $options['unique'] = true;

        $this->index($columns, null, null, $options);

        return $this;
    }

    /**
     * Specify a non blocking index for the collection.
     *
     * @param  string|array $columns
     * @return Blueprint
     */
    public function background($columns = null)
    {
        $columns = $this->fluent($columns);

        $this->index($columns, null, null, ['background' => true]);

        return $this;
    }

    /**
     * Specify a sparse index for the collection.
     *
     * @param  string|array $columns
     * @param  array        $options
     * @return Blueprint
     */
    public function sparse($columns = null, $options = [])
    {
        $columns = $this->fluent($columns);

        $options['sparse'] = true;

        $this->index($columns, null, null, $options);

        return $this;
    }

    /**
     * Specify the number of seconds after wich a document should be considered expired based,
     * on the given single-field index containing a date.
     *
     * @param  string|array $columns
     * @param  int          $seconds
     * @return Blueprint
     */
    public function expire($columns, $seconds)
    {
        $columns = $this->fluent($columns);

        $this->index($columns, null, null, ['expireAfterSeconds' => $seconds]);

        return $this;
    }

    /**
     * @inheritdoc
     */
    public function create()
    {
        $collection = $this->collection->getCollectionName();

        $db = $this->connection->getMongoDB();

        // Ensure the collection is created.
        $db->createCollection($collection);
    }

    /**
     * @inheritdoc
     */
    public function drop()
    {
        $this->collection->drop();
    }

    /**
     * @inheritdoc
     */
    public function addColumn($type, $name, array $parameters = [])
    {
        $this->fluent($name);

        return $this;
    }

    /**
     * Specify a sparse and unique index for the collection.
     *
     * @param  string|array $columns
     * @param  array        $options
     * @return Blueprint
     */
    public function sparse_and_unique($columns = null, $options = [])
    {
        $columns = $this->fluent($columns);

        $options['sparse'] = true;
        $options['unique'] = true;

        $this->index($columns, null, null, $options);

        return $this;
    }

    /**
     * Allow fluent columns.
     *
     * @param  string|array $columns
     * @return string|array
     */
    protected function fluent($columns = null)
    {
        if (is_null($columns)) {
            return $this->columns;
        } elseif (is_string($columns)) {
            return $this->columns = [$columns];
        } else {
            return $this->columns = $columns;
        }
    }

    /**
     * Allows the use of unsupported schema methods.
     *
     * @param $method
     * @param $args
     * @return Blueprint
     */
    public function __call($method, $args)
    {
        // Dummy.
        return $this;
    }
}
