<?php
/**
 * HTTP client for the hub's bw-guides/v1 REST API.
 */

defined( 'ABSPATH' ) || exit;

class BW_Guides_Client {

	const SCHEMA_VERSION = 1;
	const TIMEOUT        = 15;

	public function health() {
		$response = wp_remote_get(
			BW_Guides_Settings::hub_url() . '/wp-json/bw-guides/v1/health',
			array(
				'timeout'   => self::TIMEOUT,
				'sslverify' => true,
			)
		);
		if ( is_wp_error( $response ) ) {
			return $response;
		}
		if ( 200 !== wp_remote_retrieve_response_code( $response ) ) {
			return new WP_Error( 'bw_guides_hub_unreachable', __( 'The guides hub is not responding.', 'bw-guides' ) );
		}
		return json_decode( wp_remote_retrieve_body( $response ), true );
	}

	public function manifest() {
		return $this->get_json( '/wp-json/bw-guides/v1/manifest', array( 'schema' => self::SCHEMA_VERSION ) );
	}

	public function guides( $ids ) {
		return $this->get_json(
			'/wp-json/bw-guides/v1/guides',
			array( 'include' => implode( ',', array_map( 'intval', (array) $ids ) ) )
		);
	}

	private function get_json( $path, $args ) {
		$key = BW_Guides_Settings::site_key();
		if ( '' === $key ) {
			return new WP_Error( 'bw_guides_no_key', __( 'No site key configured. Enter one under Guides → Settings.', 'bw-guides' ) );
		}

		$url = add_query_arg(
			array_merge( $args, array( 'client' => BW_GUIDES_VERSION ) ),
			BW_Guides_Settings::hub_url() . $path
		);

		$response = wp_remote_get(
			$url,
			array(
				'timeout'   => self::TIMEOUT,
				'sslverify' => true,
				'headers'   => array( 'X-BW-Guides-Key' => $key ),
			)
		);
		if ( is_wp_error( $response ) ) {
			return $response;
		}

		$code = wp_remote_retrieve_response_code( $response );
		$body = json_decode( wp_remote_retrieve_body( $response ), true );

		if ( 200 !== $code ) {
			$err_code = ( is_array( $body ) && ! empty( $body['code'] ) ) ? (string) $body['code'] : 'bw_guides_http_' . $code;
			$message  = ( is_array( $body ) && ! empty( $body['message'] ) )
				? (string) $body['message']
				/* translators: %d: HTTP status code */
				: sprintf( __( 'The guides hub returned HTTP %d.', 'bw-guides' ), $code );
			return new WP_Error( $err_code, $message );
		}

		if ( ! is_array( $body ) ) {
			return new WP_Error( 'bw_guides_bad_json', __( 'The guides hub returned invalid JSON.', 'bw-guides' ) );
		}

		return $body;
	}
}
