<?php
class Tinify_Source
{
  private $url, $commands;

  public static function fromFile($path)
  {
    return self::fromBuffer(file_get_contents($path));
  }

  public static function fromBuffer($string)
  {
    $response = Tinify_Tinify::getClient()->request('post', '/shrink', $string);
    return new self($response['headers']['location']);
  }

  public static function fromUrl($url)
  {
    $body = ['source' => ['url' => $url]];
    $response = Tinify_Tinify::getClient()->request('post', '/shrink', $body);
    return new self($response['headers']['location']);
  }

  public function __construct($url, $commands = [])
  {
    $this->url = $url;
    $this->commands = $commands;
  }

  public function preserve()
  {
    $options = $this->flatten(func_get_args());
    $commands = array_merge($this->commands, ['preserve' => $options]);
    return new self($this->url, $commands);
  }

  public function resize($options)
  {
    $commands = array_merge($this->commands, ['resize' => $options]);
    return new self($this->url, $commands);
  }

  public function store($options)
  {
    $response = Tinify_Tinify::getClient()->request('post', $this->url, array_merge($this->commands, ['store' => $options]));
    return new Tinify_Result($response['headers'], $response['body']);
  }

  public function result()
  {
    $response = Tinify_Tinify::getClient()->request('get', $this->url, $this->commands);
    return new Tinify_Result($response['headers'], $response['body']);
  }

  public function toFile($path)
  {
    return $this->result()->toFile($path);
  }

  public function toBuffer()
  {
    return $this->result()->toBuffer();
  }

  private static function flatten($options)
  {
    $flattened = [];
    foreach ($options as $option) {
      if (is_array($option)) {
        $flattened = array_merge($flattened, $option);
      } else {
        array_push($flattened, $option);
      }
    }
    return $flattened;
  }
}
