<?php
namespace SabaiApps\Directories\Platform\WordPress;

use SabaiApps\Directories\Application;
use SabaiApps\Directories\Exception;

class Util {

	public static function createPage( Platform $platform, $slug, $title, $lang = false ) {
		if ( $page = get_page_by_path( $slug ) ) {
			wp_publish_post( $page->ID );
			return $page->ID;
		}
		if ( strpos( $slug, '/' ) ) { // not a root page
			if ( ! $parent_page = get_page_by_path( substr( $slug, 0, strrpos( $slug, '/' ) ) ) ) {
				// parent page must exist
				return;
			}
			$slug   = basename( $slug );
			$parent = $parent_page->ID;
		} else {
			$parent = 0;
		}

		// Create a new page for this slug
		$page = array(
			'comment_status' => 'closed',
			'ping_status'    => 'closed',
			'post_content'   => '',
			'post_date'      => current_time( 'mysql' ),
			'post_date_gmt'  => current_time( 'mysql', 1 ),
			'post_name'      => $slug,
			'post_status'    => 'publish',
			'post_title'     => $title,
			'post_type'      => 'page',
			'post_parent'    => $parent,
		);
		return wp_insert_post( $page );
	}

	public static function updateDatabase( Platform $platform, $schema, $previousSchema = null ) {
		global $wpdb;
		if ( isset( $schema ) ) {
			if ( is_string( $schema ) ) {
				$schema = include $schema;
			}
			$schema = self::_updateDatabaseSchema( $wpdb, $schema );
			if ( $schema['sql'] ) {
				require_once ABSPATH . 'wp-admin/includes/upgrade.php';
				dbDelta( $schema['sql'] );
			}
			foreach ( $schema['inserts'] as $table_name => $inserts ) {
				foreach ( $inserts as $insert ) {
					$wpdb->insert( $table_name, $insert );
				}
			}
		} elseif ( isset( $previousSchema ) ) {
			if ( is_string( $previousSchema ) ) {
				$previousSchema = include $previousSchema;
			}
			if ( ! empty( $previousSchema['tables'] ) ) {
				foreach ( array_keys( $previousSchema['tables'] ) as $table ) {
					$wpdb->query( 'DROP TABLE IF EXISTS ' . $wpdb->prefix . 'drts_' . $table . ';' );
				}
			}
		}
	}

	protected static function _updateDatabaseSchema( $wpdb, $schema ) {
		$ret = array(
			'sql'     => null,
			'inserts' => array(),
		);
		if ( empty( $schema['tables'] ) ) {
			return $ret;
		}

		$sql          = array();
		$table_prefix = $wpdb->prefix . 'drts_';
		// Get charset/collation from the posts table and use them for new tables
		$posts_table_status = $wpdb->get_row( "SHOW TABLE STATUS LIKE '" . $wpdb->posts . "'" );
		if ( $posts_table_status
			&& $posts_table_status->Collation
			&& ( $collation_parts = explode( '_', $posts_table_status->Collation ) )
		) {
			$charset   = $collation_parts[0];
			$collation = $posts_table_status->Collation;
		} else {
			$charset   = $wpdb->charset;
			$collation = $wpdb->collate;
		}
		foreach ( $schema['tables'] as $table => $table_info ) {
			$table_name = $table_prefix . $table;
			if ( strlen( $table_name ) > 64 ) {
				throw new Exception\RuntimeException( 'Table name is too long: ' . $table_name );
			}
			$columns = array();
			foreach ( $table_info['fields'] as $column => $column_info ) {
				switch ( $column_info['type'] ) {
					case Application::COLUMN_BOOLEAN:
						$columns[] = sprintf(
							'%s tinyint(1) DEFAULT \'%d\'%s',
							$column,
							! empty( $column_info['default'] ) ? 1 : 0,
							false === @$column_info['notnull'] ? '' : ' NOT NULL'
						);
						break;
					case Application::COLUMN_DECIMAL:
						$scale     = ! isset( $column_info['scale'] ) ? 2 : $column_info['scale'];
						$columns[] = sprintf(
							'%s decimal(%d,%d)%s DEFAULT \'%s\'%s',
							$column,
							empty( $column_info['length'] ) ? 10 : $column_info['length'],
							$scale,
							! empty( $column_info['unsigned'] ) ? ' unsigned' : '',
							isset( $column_info['default'] ) ? $column_info['default'] : '0.' . str_repeat( '0', $scale ),
							false === @$column_info['notnull'] ? '' : ' NOT NULL'
						);
						break;
					case Application::COLUMN_INTEGER:
						$length    = empty( $column_info['length'] ) ? 20 : $column_info['length'];
						$type      = $length > 10 ? 'bigint' : 'int';
						$columns[] = sprintf(
							'%s %s(%d)%s%s%s%s',
							$column,
							$type,
							$length,
							! empty( $column_info['unsigned'] ) ? ' unsigned' : '',
							empty( $column_info['autoincrement'] ) && isset( $column_info['default'] ) ? " DEFAULT '" . intval( $column_info['default'] ) . "'" : '',
							false === @$column_info['notnull'] ? '' : ' NOT NULL',
							empty( $column_info['autoincrement'] ) ? '' : ' AUTO_INCREMENT'
						);
						break;
					case Application::COLUMN_TEXT:
						$columns[] = sprintf(
							'%s text%s',
							$column,
							false === @$column_info['notnull'] ? '' : ' NOT NULL'
						);
						break;
					case Application::COLUMN_JSON:
						$columns[] = sprintf(
							'%s longtext%s',
							$column,
							false === @$column_info['notnull'] ? '' : ' NOT NULL'
						);
						break;
					case Application::COLUMN_VARCHAR:
						$columns[] = sprintf(
							'%s varchar(%d) DEFAULT \'%s\'%s',
							$column,
							empty( $column_info['length'] ) ? 255 : $column_info['length'],
							(string) @$column_info['default'],
							false === @$column_info['notnull'] ? '' : ' NOT NULL'
						);
						break;
					case Application::COLUMN_DATETIME:
						$columns[] = sprintf(
							'%s datetime %s DEFAULT \'%s\'',
							$column,
							false === @$column_info['notnull'] ? '' : ' NOT NULL',
							isset( $column_info['default'] ) ? (string) $column_info['default'] : '0000-00-00 00:00:00'
						);
						break;
				}
			}
			foreach ( $table_info['indexes'] as $index => $index_info ) {
				$index_fields = array();
				foreach ( $index_info['fields'] as $field => $field_info ) {
					$index_fields[] = isset( $field_info['length'] ) ? $field . '(' . $field_info['length'] . ')' : $field;
				}
				if ( ! empty( $index_info['primary'] ) ) {
					$columns[] = sprintf( 'PRIMARY KEY (%s)', implode( ',', $index_fields ) );
				} elseif ( ! empty( $index_info['unique'] ) ) {
					$columns[] = sprintf( 'UNIQUE KEY `%s` (%s)', $index, implode( ',', $index_fields ) );
				} else {
					$columns[] = sprintf( 'KEY `%s` (%s)', $index, implode( ',', $index_fields ) );
				}
			}
			if ( ! empty( $table_info['initialization'] ) ) {
				foreach ( $table_info['initialization'] as $init_type => $init_data ) {
					switch ( $init_type ) {
						case 'insert';
							$ret['inserts'][ $table_name ] = $init_data;
							break;
					}
				}
			}

			$charset_collate = '';
			if ( ! empty( $charset ) ) {
				$charset_collate .= ' DEFAULT CHARACTER SET ' . $charset;
			}
			if ( ! empty( $collation ) ) {
				$charset_collate .= ' COLLATE ' . $collation;
			}
			$sql[ $table_name ] = sprintf(
				'CREATE TABLE %s (
  %s
)%s;',
				$table_name,
				implode( ",\n", $columns ),
				$charset_collate
			);
		}
		if ( ! empty( $sql ) ) {
			$ret['sql'] = implode( "\n", $sql );
		}
		return $ret;
	}

	public static function getRewriteRules( Platform $platform, $lang ) {
		$ret = array();
		if ( $page_slugs = $platform->getPageSlugs( $lang ) ) {
			if ( ! empty( $page_slugs[0] ) ) {
				arsort( $page_slugs[0] );
				foreach ( $page_slugs[0] as $slug ) {
					// if ($excluded_slugs = apply_filters('drts_wordpresscontent_post_type_path_exclude_slugs', [], $slug, $lang)) {
						// Exclude certain slugs from being treated as plugin page routes
					// $ret[preg_quote($slug) . '/(' . implode('|', $excluded_slugs) . ')/?$'] = 'index.php?pagename=' . $slug . '/$matches[1]';
					// }
					$ret[ preg_quote( $slug ) . '/(.*)$' ] = 'index.php?pagename=' . $slug
						. '&drts_route=' . $slug . '/$matches[1]'
						. '&drts_lang=' . $lang;
					$ret[ preg_quote( $slug ) . '/?$' ]    = 'index.php?pagename=' . $slug
						. '&drts_route=' . $slug
						. '&drts_lang=' . $lang;
				}
			}
		}

		$ret['_drts/(.*)$'] = 'index.php?drts_route=_drts/$matches[1]';
		$ret['_drts/?$']    = 'index.php?drts_route=_drts';

		return $ret;
	}
}
