<?php
/**
 * Wasabi destination. Hot cloud storage with S3 API.
 *
 * @package Backreload\Destinations
 */

namespace Backreload\Destinations;

use Backreload\Models\DestinationRecord;

if ( ! defined( 'ABSPATH' ) ) { exit; }

class WasabiDestination extends S3compatDestination {

	public static function type(): string  { return 'wasabi'; }
	public static function label(): string { return 'Wasabi'; }

	/** Wasabi region → endpoint hostname map. */
	private const ENDPOINTS = [
		'us-east-1'      => 'https://s3.wasabisys.com',
		'us-east-2'      => 'https://s3.us-east-2.wasabisys.com',
		'us-central-1'   => 'https://s3.us-central-1.wasabisys.com',
		'us-west-1'      => 'https://s3.us-west-1.wasabisys.com',
		'eu-central-1'   => 'https://s3.eu-central-1.wasabisys.com',
		'eu-west-1'      => 'https://s3.eu-west-1.wasabisys.com',
		'ap-northeast-1' => 'https://s3.ap-northeast-1.wasabisys.com',
	];

	/** Wasabi endpoint is derived from the chosen region. */
	protected function resolve_endpoint( DestinationRecord $dest ): string {
		$region = (string) ( $dest->config['region'] ?? 'us-east-1' );
		return self::ENDPOINTS[ $region ] ?? self::ENDPOINTS['us-east-1'];
	}

	public static function config_schema(): array {
		$regions = [
			'us-east-1' => 'https://s3.wasabisys.com',
			'us-east-2' => 'https://s3.us-east-2.wasabisys.com',
			'us-central-1' => 'https://s3.us-central-1.wasabisys.com',
			'us-west-1' => 'https://s3.us-west-1.wasabisys.com',
			'eu-central-1' => 'https://s3.eu-central-1.wasabisys.com',
			'eu-west-1' => 'https://s3.eu-west-1.wasabisys.com',
			'ap-northeast-1' => 'https://s3.ap-northeast-1.wasabisys.com',
		];
		return [
			[ 'key' => 'region',     'label' => 'Region',             'type' => 'select', 'options' => array_keys( $regions ), 'default' => 'us-east-1', 'required' => true ],
			[ 'key' => 'bucket',     'label' => 'Bucket',             'type' => 'text',     'required' => true ],
			[ 'key' => 'access_key', 'label' => 'Access key ID',      'type' => 'text',     'required' => true, 'secret' => true ],
			[ 'key' => 'secret_key', 'label' => 'Secret access key',  'type' => 'password', 'required' => true, 'secret' => true ],
			[ 'key' => 'prefix',     'label' => 'Object key prefix',  'type' => 'text',     'default' => 'wordpress/' ],
			[ 'key' => 'sse',        'label' => 'Server-side encryption', 'type' => 'select',
			  'options' => [ 'none', 'AES256' ], 'default' => 'AES256' ],
		];
	}

	/**
	 * Walkthrough for the Wasabi console. The major differences from AWS
	 * are:
	 *   - Wasabi has its own per-bucket access policies via the "Sub-user"
	 *     pattern. We recommend creating a dedicated sub-user scoped to a
	 *     single bucket so a leaked key can't touch the rest of the
	 *     account (same reasoning as AWS, different UI path).
	 *   - The region must match the bucket's region. Wasabi rejects with
	 *     "InvalidLocationConstraint" if it doesn't — surfaced clearly in
	 *     step 2 here so users don't get cryptic errors later.
	 */
	public static function setup_help(): array {
		$policy_json = wp_json_encode(
			[
				'Version'   => '2012-10-17',
				'Statement' => [
					[
						'Effect'   => 'Allow',
						'Action'   => [ 's3:ListBucket' ],
						'Resource' => 'arn:aws:s3:::YOUR-BUCKET-NAME',
					],
					[
						'Effect'   => 'Allow',
						'Action'   => [ 's3:PutObject', 's3:GetObject', 's3:DeleteObject' ],
						'Resource' => 'arn:aws:s3:::YOUR-BUCKET-NAME/*',
					],
				],
			],
			JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES
		);
		return [
			'title'    => 'Setup help: where do I get the Access key and Secret?',
			'provider' => 'Wasabi',
			'steps' => [
				'Sign in to the <a href="https://console.wasabisys.com/" target="_blank" rel="noopener">Wasabi Console</a>.',
				'Open <strong>Buckets → Create Bucket</strong>. Name the bucket, pick a region (note which. you\'ll select the same region in the Region dropdown above). Leave default settings; Wasabi buckets are private by default. Create it.',
				'Open <strong>Users → Create User</strong>. Pick <strong>Programmatic (create API key)</strong> as the access type; this user only needs an API key, no console login.',
				'On the <strong>Set Permissions</strong> step, click <strong>Create new policy</strong>. Paste the policy JSON shown in the box below, replacing <code>YOUR-BUCKET-NAME</code> with the bucket from step 2. Name the policy <code>BackReloadBucketPolicy</code>, save.',
				'Continue through the wizard. After creation, Wasabi shows the <strong>Access Key</strong> and <strong>Secret Key</strong> ONCE, so copy both immediately. The dialog also offers a CSV download as a backup.',
				'Paste the keys into the fields above, pick the same Region you used in step 2, and click Save. The "Test" button will probe the bucket so any typos surface right away.',
			],
			'callouts' => [
				[
					'label' => 'Minimum bucket policy (replace YOUR-BUCKET-NAME)',
					'value' => (string) $policy_json,
					'help'  => 'Wasabi accepts the same JSON policy format as AWS S3. Grants only write/read/delete on this one bucket, a leaked key can\'t touch anything else.',
				],
			],
		];
	}
}
