diff --git a/src/CurrencyConverter.php b/src/CurrencyConverter.php new file mode 100644 index 00000000..0d77b44b --- /dev/null +++ b/src/CurrencyConverter.php @@ -0,0 +1,107 @@ + + * @license http://opensource.org/licenses/MIT MIT + * @link https://github.com/apiki/back-end-challenge + */ + +declare(strict_types=1); + +namespace App; + +/** + * Class CurrencyConverter + * + * @category Challenge + * @package Back-end + * @author Seu Nome + * @license http://opensource.org/licenses/MIT MIT + * @link https://github.com/apiki/back-end-challenge + */ +class CurrencyConverter +{ + private const CURRENCY_SYMBOLS = [ + 'USD' => '$', + 'BRL' => 'R$', + 'EUR' => '€', + ]; + + private const VALID_CONVERSIONS = [ + 'BRL' => ['USD', 'EUR'], + 'USD' => ['BRL'], + 'EUR' => ['BRL'], + ]; + + /** + * Convert currency. + * + * @param float $amount The amount to convert. + * @param string $from The source currency. + * @param string $to The target currency. + * @param float $rate The exchange rate. + * + * @return array + */ + public function convert( + float $amount, + string $from, + string $to, + float $rate + ): array { + $this->_validate($amount, $from, $to, $rate); + + $convertedValue = $amount * $rate; + + return [ + 'valorConvertido' => $convertedValue, + 'simboloMoeda' => self::CURRENCY_SYMBOLS[$to], + ]; + } + + /** + * Validate conversion parameters. + * + * @param float $amount The amount to convert. + * @param string $from The source currency. + * @param string $to The target currency. + * @param float $rate The exchange rate. + * + * @return void + * + * @throws \InvalidArgumentException When parameters are invalid. + */ + private function _validate( + float $amount, + string $from, + string $to, + float $rate + ): void { + if ($amount <= 0) { + throw new \InvalidArgumentException('Invalid amount.'); + } + + if ($rate <= 0) { + throw new \InvalidArgumentException('Invalid rate.'); + } + + if (!isset(self::CURRENCY_SYMBOLS[$from])) { + throw new \InvalidArgumentException('Invalid source currency.'); + } + + if (!isset(self::CURRENCY_SYMBOLS[$to])) { + throw new \InvalidArgumentException('Invalid target currency.'); + } + + if (!isset(self::VALID_CONVERSIONS[$from]) + || !in_array($to, self::VALID_CONVERSIONS[$from]) + ) { + throw new \InvalidArgumentException('Invalid conversion.'); + } + } +} diff --git a/src/Router.php b/src/Router.php new file mode 100644 index 00000000..b5745ead --- /dev/null +++ b/src/Router.php @@ -0,0 +1,90 @@ + + * @license http://opensource.org/licenses/MIT MIT + * @link https://github.com/apiki/back-end-challenge + */ + +declare(strict_types=1); + +namespace App; + +/** + * Class Router + * + * @category Challenge + * @package Back-end + * @author Seu Nome + * @license http://opensource.org/licenses/MIT MIT + * @link https://github.com/apiki/back-end-challenge + */ +class Router +{ + /** + * Handle the incoming request. + * + * @return void + */ + public function handleRequest(): void + { + header('Content-Type: application/json'); + + $uri = $_SERVER['REQUEST_URI'] ?? ''; + $uri = parse_url($uri, PHP_URL_PATH); + $uri = preg_replace('#^/exchange#', '', $uri); + + $parts = explode('/', trim($uri, '/')); + + if (count($parts) < 4 || empty($parts[0])) { + $this->_sendError('Missing required parameters.', 400); + return; + } + + list($amount, $from, $to, $rate) = $parts; + + if (!is_numeric($amount) || !is_numeric($rate)) { + $this->_sendError('Invalid numeric value.', 400); + return; + } + + if ($from !== strtoupper($from) || $to !== strtoupper($to)) { + $this->_sendError('Currency must be uppercase.', 400); + return; + } + + try { + $converter = new CurrencyConverter(); + $result = $converter->convert( + (float) $amount, + $from, + $to, + (float) $rate + ); + + http_response_code(200); + echo json_encode($result); + } catch (\InvalidArgumentException $e) { + $this->_sendError($e->getMessage(), 400); + } + } + + /** + * Send an error response. + * + * @param string $message The error message. + * @param int $code The HTTP status code. + * + * @return void + */ + private function _sendError(string $message, int $code): void + { + http_response_code($code); + echo json_encode(['error' => $message]); + } +} diff --git a/src/index.php b/src/index.php index 92841bc8..df634a93 100644 --- a/src/index.php +++ b/src/index.php @@ -16,3 +16,5 @@ require __DIR__ . '/../vendor/autoload.php'; +$router = new App\Router(); +$router->handleRequest();