<?php
/**
 * Sets up the plugin.
 *
 * @package WPDiscourse
 */

namespace WPDiscourse\Discourse;

use WPDiscourse\Shared\PluginUtilities;

/**
 * Class Discourse
 */
class Discourse {
	use PluginUtilities;

	/**
	 * Gives access to the plugin options.
	 *
	 * @access protected
	 * @var mixed|void
	 */
	protected $options;

	/**
	 * The connection options array.
	 *
	 * @access protected
	 * @var array
	 */
	protected $discourse_connect = array(
		'url'              => '',
		'api-key'          => '',
		'publish-username' => 'system',
	);

	/**
	 * The publishing options array.
	 *
	 * @access protected
	 * @var array
	 */
	protected $discourse_publish = array(
		'display-subcategories'       => 0,
		'publish-category'            => '',
		'publish-category-update'     => 0,
		'full-post-content'           => 0,
		'allow-tags'                  => 0,
		'max-tags'                    => 5,
		'publish-as-unlisted'         => 0,
		'custom-excerpt-length'       => 55,
		'add-featured-link'           => 0,
		'auto-publish'                => 0,
		'force-publish'               => 0,
		'force-publish-max-age'       => 0,
		'publish-failure-notice'      => 0,
		'publish-failure-email'       => '',
		'auto-track'                  => 1,
		'allowed_post_types'          => array( 'post' ),
		'hide-discourse-name-field'   => 0,
		'discourse-username-editable' => 0,
	);

	/**
	 * The commenting options array.
	 *
	 * @access protected
	 * @var array
	 */
	protected $discourse_comment = array(
		'enable-discourse-comments' => 0,
		'comment-type'              => 'display-comments',
		'ajax-load'                 => 0,
		'cache-html'                => 0,
		'clear-cached-comment-html' => 0,
		'discourse-new-tab'         => 0,
		'comment-sync-period'       => 10,
		'hide-wordpress-comments'   => 0,
		'show-existing-comments'    => 0,
		'existing-comments-heading' => '',
		'max-comments'              => 5,
		'min-replies'               => 1,
		'min-score'                 => 0,
		'min-trust-level'           => 1,
		'bypass-trust-level-score'  => 50,
		'custom-datetime-format'    => '',
		'only-show-moderator-liked' => 0,
		'load-comment-css'          => 0,
	);

	/**
	 * The configurable text options array.
	 *
	 * @access protected
	 * @var array
	 */
	protected $discourse_configurable_text = array(
		'discourse-link-text'         => '',
		'start-discussion-text'       => 'Start the discussion at',
		'continue-discussion-text'    => 'Continue the discussion at',
		'join-discussion-text'        => 'Join the discussion at',
		'comments-singular-text'      => 'Comment',
		'comments-plural-text'        => 'Comments',
		'no-comments-text'            => 'Join the Discussion',
		'notable-replies-text'        => 'Notable Replies',
		'comments-not-available-text' => 'Comments are not currently available for this post.',
		'participants-text'           => 'Participants',
		'published-at-text'           => 'Originally published at:',
		'single-reply-text'           => 'Reply',
		'many-replies-text'           => 'Replies',
		'more-replies-more-text'      => 'more',
		'external-login-text'         => 'Log in with Discourse',
		'link-to-discourse-text'      => 'Link your account to Discourse',
		'linked-to-discourse-text'    => 'Your account is linked with Discourse!',
	);

	/**
	 * The webhook options array.
	 *
	 * @access protected
	 * @var array
	 */
	protected $discourse_webhook = array(
		'use-discourse-webhook'      => 0,
		'webhook-secret'             => '',
		'use-discourse-user-webhook' => 0,
		'webhook-match-user-email'   => 0,
	);

	/**
	 * The sso_common options array.
	 *
	 * @access protected
	 * @var array
	 */
	protected $discourse_sso_common = array(
		'sso-secret' => '',
	);

	/**
	 * The sso_provider options.
	 *
	 * @access protected
	 * @var array
	 */
	protected $discourse_sso_provider = array(
		'enable-sso'                  => 0,
		'auto-create-sso-user'        => 0,
		'login-path'                  => '',
		'real-name-as-discourse-name' => 0,
		'force-avatar-update'         => 0,
		'redirect-without-login'      => 0,
	);

	/**
	 * The sso_client options.
	 *
	 * @var array
	 */
	protected $discourse_sso_client = array(
		'sso-client-enabled'             => 0,
		'sso-client-login-form-change'   => 0,
		'sso-client-login-form-redirect' => '',
		'sso-client-sync-by-email'       => 0,
		'sso-client-disable-create-user' => 0,
		'sso-client-sync-logout'         => 0,
	);

	/**
	 * The discourse_logs options.
	 *
	 * @access protected
	 * @var array
	 */
	protected $discourse_logs = array(
		'logs-enabled' => 1,
	);

	/**
	 * The array of option groups, used for assembling the options into a single array.
	 *
	 * @var array
	 */
	protected $discourse_option_groups = array(
		'discourse_connect',
		'discourse_publish',
		'discourse_comment',
		'discourse_configurable_text',
		'discourse_webhook',
		'discourse_sso_common',
		'discourse_sso_provider',
		'discourse_sso_client',
		'discourse_logs',
	);

	/**
	 * Discourse constructor.
	 */
	public function __construct() {
		add_action( 'init', array( $this, 'initialize_plugin' ) );
		add_filter( 'allowed_redirect_hosts', array( $this, 'allow_discourse_redirect' ) );
		add_filter( 'wp_kses_allowed_html', array( $this, 'allow_time_tag' ) );
		add_action( 'admin_head', array( $this, 'wpdc_admin_head' ) );
	}

	/**
	 * Initializes the plugin configuration, loads the text domain etc.
	 */
	public function initialize_plugin() {
		load_plugin_textdomain( 'wp-discourse', false, basename( __DIR__ ) . '/languages' );
		$this->options = $this->get_options();

		// Set the Discourse domain name option.
		$discourse_url = ! empty( $this->options['url'] ) ? $this->options['url'] : null;
		$domain_name   = wp_parse_url( $discourse_url, PHP_URL_HOST );
		update_option( 'wpdc_discourse_domain', $domain_name );
		update_option( 'discourse_option_groups', $this->discourse_option_groups );

		foreach ( $this->discourse_option_groups as $group_name ) {
			if ( 'discourse_configurable_text' === $group_name && get_option( 'discourse_configurable_text' ) ) {
				$saved_values   = get_option( 'discourse_configurable_text' );
				$default_values = $this->discourse_configurable_text;
				$merged_values  = array_merge( $default_values, $saved_values );
				array_walk( $merged_values, self::class . '::register_text_translations' );
				update_option( $group_name, $merged_values );
			} else {
				add_option( $group_name, $this->$group_name );
			}
		}

		// Transfer 'use-discourse-comments' and 'add-join-link' options. Plugin version 1.7.7.
		$commenting_options = get_option( 'discourse_comment' );
		if ( ! empty( $commenting_options['use-discourse-comments'] ) || ! empty( $commenting_options['add-join-link'] ) ) {
			$commenting_options['enable-discourse-comments'] = 1;
			$commenting_options['comment-type']              = ! empty( $this->options['use-discourse-comments'] ) ? 'display-comments' : 'display-comments-link';
		}
		unset( $commenting_options['use-discourse-comments'] );
		unset( $commenting_options['add-join-link'] );
		update_option( 'discourse_comment', $commenting_options );

		// Create a backup for the discourse_configurable_text option.
		update_option( 'discourse_configurable_text_backup', $this->discourse_configurable_text );
		update_option( 'discourse_version', WPDISCOURSE_VERSION );

		$this->register_assets();
	}

	/**
	 * Adds the Discourse forum domain name to the allowed hosts for wp_safe_redirect().
	 *
	 * @param array $hosts The array of allowed hosts.
	 *
	 * @return array
	 */
	public function allow_discourse_redirect( $hosts ) {
		$discourse_domain = get_option( 'wpdc_discourse_domain' );

		if ( $discourse_domain ) {
			$hosts[] = $discourse_domain;
		}

		return $hosts;
	}

	/**
	 * Allow the time tag - used in Discourse comments.
	 *
	 * @param array $allowedposttags The array of allowed html tags.
	 *
	 * @return array
	 */
	public function allow_time_tag( $allowedposttags ) {
		$allowedposttags['time'] = array(
			'datetime' => array(),
		);

		return $allowedposttags;
	}

	/**
	 * Adds WP Discourse tags to the <head> in the admin panel.
	 */
	public function wpdc_admin_head() {
		$this->wpdc_icon();
		$this->wpdc_url();
	}

	/**
	 * Adds the WP Discourse icon to the <head> for use in the client.
	 */
	public function wpdc_icon() {
		echo '<meta name="wpdc-icon" content="' . esc_html( WPDISCOURSE_LOGO ) . '" />';
	}

	/**
	 * Adds the WP Discourse URL to the <head> for use in the client.
	 */
	public function wpdc_url() {
    if ( empty( $this->options['url'] ) ) {
				return;
    }
		echo '<meta name="wpdc-url" content="' . esc_html( $this->options['url'] ) . '" />';
	}

	/**
	 * Registers assets on initialization
	 */
	public function register_assets() {
		$style_path  = '../css/comments.css';
		$script_path = '../js/load-comments.js';

		wp_register_script( 'load_comments_js', plugins_url( $script_path, __FILE__ ), array( 'jquery' ), filemtime( plugin_dir_path( __FILE__ ) . $script_path ), true );
		wp_register_style( 'comment_styles', plugins_url( $style_path, __FILE__ ), array(), filemtime( plugin_dir_path( __FILE__ ) . $style_path ) );
	}
}
