<?php

namespace DrewM\MailChimp;

/**
 * A MailChimp Batch operation.
 * http://developer.mailchimp.com/documentation/mailchimp/reference/batches/
 *
 * @author Drew McLellan <drew.mclellan@gmail.com>
 */
class Batch
{
    private $MailChimp;

    private $operations = array();
    private $batch_id;

    public function __construct(MailChimp $MailChimp, $batch_id = null)
    {
        $this->MailChimp = $MailChimp;
        $this->batch_id  = $batch_id;
    }

    /**
     * Add an HTTP DELETE request operation to the batch - for deleting data
     *
     * @param   string $id     ID for the operation within the batch
     * @param   string $method URL of the API request method
     *
     * @return  void
     */
    public function delete($id, $method)
    {
        $this->queueOperation('DELETE', $id, $method);
    }

    /**
     * Add an HTTP GET request operation to the batch - for retrieving data
     *
     * @param   string $id     ID for the operation within the batch
     * @param   string $method URL of the API request method
     * @param   array  $args   Assoc array of arguments (usually your data)
     *
     * @return  void
     */
    public function get($id, $method, $args = array())
    {
        $this->queueOperation('GET', $id, $method, $args);
    }

    /**
     * Add an HTTP PATCH request operation to the batch - for performing partial updates
     *
     * @param   string $id     ID for the operation within the batch
     * @param   string $method URL of the API request method
     * @param   array  $args   Assoc array of arguments (usually your data)
     *
     * @return  void
     */
    public function patch($id, $method, $args = array())
    {
        $this->queueOperation('PATCH', $id, $method, $args);
    }

    /**
     * Add an HTTP POST request operation to the batch - for creating and updating items
     *
     * @param   string $id     ID for the operation within the batch
     * @param   string $method URL of the API request method
     * @param   array  $args   Assoc array of arguments (usually your data)
     *
     * @return  void
     */
    public function post($id, $method, $args = array())
    {
        $this->queueOperation('POST', $id, $method, $args);
    }

    /**
     * Add an HTTP PUT request operation to the batch - for creating new items
     *
     * @param   string $id     ID for the operation within the batch
     * @param   string $method URL of the API request method
     * @param   array  $args   Assoc array of arguments (usually your data)
     *
     * @return  void
     */
    public function put($id, $method, $args = array())
    {
        $this->queueOperation('PUT', $id, $method, $args);
    }

    /**
     * Execute the batch request
     *
     * @param int $timeout Request timeout in seconds (optional)
     *
     * @return  array|false   Assoc array of API response, decoded from JSON
     */
    public function execute($timeout = 10)
    {
        $req = array('operations' => $this->operations);

        $result = $this->MailChimp->post('batches', $req, $timeout);

        if ($result && isset($result['id'])) {
            $this->batch_id = $result['id'];
        }

        return $result;
    }

    /**
     * Check the status of a batch request. If the current instance of the Batch object
     * was used to make the request, the batch_id is already known and is therefore optional.
     *
     * @param string $batch_id ID of the batch about which to enquire
     *
     * @return  array|false   Assoc array of API response, decoded from JSON
     */
    public function check_status($batch_id = null)
    {
        if ($batch_id === null && $this->batch_id) {
            $batch_id = $this->batch_id;
        }

        return $this->MailChimp->get('batches/' . $batch_id);
    }

    /**
     *  Get operations
     *
     * @return array
     */
    public function get_operations()
    {
        return $this->operations;
    }

    /**
     * Add an operation to the internal queue.
     *
     * @param   string $http_verb GET, POST, PUT, PATCH or DELETE
     * @param   string $id        ID for the operation within the batch
     * @param   string $method    URL of the API request method
     * @param   array  $args      Assoc array of arguments (usually your data)
     *
     * @return  void
     */
    private function queueOperation($http_verb, $id, $method, $args = null)
    {
        $operation = array(
            'operation_id' => $id,
            'method'       => $http_verb,
            'path'         => $method,
        );

        if ($args) {
            if ($http_verb == 'GET') {
                $key             = 'params';
                $operation[$key] = $args;
            } else {
                $key             = 'body';
                $operation[$key] = json_encode($args);
            }
        }

        $this->operations[] = $operation;
    }
}
