<?php
// Copyright (c) Pickware GmbH. All rights reserved.
// This file is part of software that is released under a proprietary license.
// You must not copy, modify, distribute, make publicly available, or execute
// its contents or parts thereof without express permission by the copyright
// holder, unless otherwise permitted by law.

namespace Shopware\Plugins\ViisonDHL\Classes\DhlRetoureApi;

use ArrayAccess;
use BadMethodCallException;

class DhlRetoureApiResponse implements ArrayAccess
{
    /**
     * @var string
     */
    private $rawResponse;

    /**
     * @var array|null
     */
    private $parsedResponse;

    /**
     * @var array
     */
    private $headers;

    /**
     * @param string $rawResponse
     * @param array $headers
     */
    public function __construct($rawResponse, array $headers)
    {
        $this->rawResponse = $rawResponse;
        $this->parsedResponse = json_decode($rawResponse, true);
        $this->headers = $headers;
    }

    /**
     * @return string
     */
    public function getRawResponse()
    {
        return $this->rawResponse;
    }

    /**
     * @inheritDoc
     */
    public function offsetExists($offset)
    {
        return isset($this->parsedResponse[$offset]);
    }

    /**
     * @inheritDoc
     */
    public function offsetGet($offset)
    {
        return $this->parsedResponse[$offset];
    }

    /**
     * @inheritDoc
     */
    public function offsetSet($offset, $value)
    {
        throw new BadMethodCallException(sprintf('Object of %s is immutable', self::class));
    }

    /**
     * @inheritDoc
     */
    public function offsetUnset($offset)
    {
        throw new BadMethodCallException(sprintf('Object of %s is immutable', self::class));
    }

    /**
     * @throws DhlRetoureException
     */
    public function assertSuccessful()
    {
        $httpStatusLine = $this->headers[0]; // [0] is always the HTTP status line
        preg_match('/HTTP\\/\\S*\\s(\\d{3})/', $httpStatusLine, $matches);
        $httpResponseStatusCode = intval($matches[1]);
        if ($httpResponseStatusCode === 403) {
            throw DhlRetoureException::webserviceUnauthorized();
        }
        if ($this->parsedResponse === null) {
            throw DhlRetoureException::unexpectedResponse($this);
        }
        if (isset($this['statusCode']) || isset($this['statusText'])) {
            throw DhlRetoureException::webserviceOffline();
        }
        if (isset($this['detail'])) {
            if ($this['detail'] === 'Empfaenger ist nicht verfuegbar.') {
                throw DhlRetoureException::invalidReceiver();
            }
            throw DhlRetoureException::webserviceRequestFailed($this['detail']);
        }
    }
}
