<?php

namespace App\Services;

use RuntimeException;

class EnvironmentFileService
{
    public function update(array $values): void
    {
        $path = base_path('.env');
        if (! file_exists($path)) {
            copy(base_path('.env.example'), $path);
        }
        $contents = file_get_contents($path);
        throw_if($contents === false, RuntimeException::class, 'The environment file could not be read.');

        foreach ($values as $key => $value) {
            $line = $key.'='.$this->escape((string) $value);
            $pattern = '/^'.preg_quote($key, '/').'=.*$/m';
            $contents = preg_match($pattern, $contents) ? preg_replace($pattern, $line, $contents) : rtrim($contents).PHP_EOL.$line.PHP_EOL;
        }

        throw_unless(is_writable($path) && file_put_contents($path, $contents, LOCK_EX) !== false, RuntimeException::class, 'The .env file is not writable.');
    }

    private function escape(string $value): string
    {
        if ($value === '' || preg_match('/[\s#="\\]/', $value)) {
            return '"'.str_replace(['\\', '"', "\r", "\n"], ['\\\\', '\\"', '', '\\n'], $value).'"';
        }

        return $value;
    }
}
