<?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\ViisonCommon\Classes\ExceptionHandling;

use Exception;
use LogicException;
use RuntimeException;
use Shopware\Components\Api\Exception\BatchInterfaceNotImplementedException;
use Shopware\Components\Api\Exception\NotFoundException;
use Shopware\Components\Api\Exception\PrivilegeException;
use Shopware\Plugins\ViisonCommon\Classes\ApiException;
use Shopware\Plugins\ViisonCommon\Classes\Exceptions\ValidationExceptions\AbstractValidationException;
use Shopware\Plugins\ViisonCommon\Components\ExceptionTranslation\ExceptionTranslator;

trait ApiExceptionHandling
{
    /**
     * @deprecated Use wrapExceptionIntoApiException instead. Pay attention that wrapExceptionIntoApiException does not
     * throw the exception but returns it. That means you need to throw the exception by yourself.
     *
     * Takes any Exception, wraps it into an ApiException and throws those.
     *
     * @param Exception $e
     * @throws ApiException always
     * @throws Exception
     */
    private function handleException(Exception $e)
    {
        throw $this->wrapExceptionIntoApiException($e);
    }

    /**
     * Takes any Exception and wraps it into an ApiException.
     *
     * Instances of \RuntimeException and \LogicException are not wrapped and will be returned unchanged.
     *
     * @param Exception $e
     * @return RuntimeException|LogicException|ApiException
     */
    private function wrapExceptionIntoApiException(Exception $e)
    {
        if ($e instanceof RuntimeException || $e instanceof LogicException) {
            return $e;
        }

        if ($e instanceof ApiException) {
            return $e;
        }

        $httpStatusCode = 500;
        if ($e instanceof AbstractValidationException) {
            $httpStatusCode = 400;
        }
        if ($e instanceof NotFoundException) {
            $httpStatusCode = 404;
        }
        if ($e instanceof PrivilegeException) {
            $httpStatusCode = 403;
        }
        if ($e instanceof BatchInterfaceNotImplementedException) {
            $httpStatusCode = 405;
        }

        /** @var ExceptionTranslator $exceptionTranslator */
        $exceptionTranslator = $this->get('viison_common.exception_translator');
        $message = $exceptionTranslator->translate($e);

        return new ApiException($message, $httpStatusCode, $e);
    }
}
