<?php

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

if ( class_exists( 'AIEO_SEO_Redirects', false ) ) {
	return;
}

class AIEO_SEO_Redirects {

	const CACHE_GROUP = 'aieo_seo';
	const RULES_KEY   = 'redirect_rules';   
	const REGEX_KEY   = 'redirect_regex';   

	
	private static $dirty = false;

	
	
	

	public static function register() {
		static $done = false;
		if ( $done ) {
			return;
		}
		$done = true;
		
		
		add_action( 'template_redirect', array( __CLASS__, 'maybe_redirect' ), 1 );
	}

	public static function maybe_redirect() {
		if ( is_admin() || ! self::active() ) {
			return;
		}
		$uri  = isset( $_SERVER['REQUEST_URI'] ) ? (string) wp_unslash( $_SERVER['REQUEST_URI'] ) : '';
		$path = self::normalize_path( $uri );

		
		
		
		$rule = self::lookup_exact( $path );
		if ( ! $rule ) {
			$rule = self::match_path( $path, self::load_regex_rules() );
		}
		if ( $rule ) {
			$code = (int) $rule['status_code'];

			if ( 410 === $code ) {
				self::record_hit( (int) $rule['id'] );
				status_header( 410 );
				nocache_headers();
				wp_die( esc_html__( 'This content is no longer available.', 'ai-eshop-optimizer' ), '', array( 'response' => 410 ) );
			}

			$target = self::resolve_target( $rule, $path );
			
			if ( '' !== $target && self::normalize_path( $target ) !== $path ) {
				self::record_hit( (int) $rule['id'] );
				wp_redirect( $target, in_array( $code, array( 301, 302, 307, 308 ), true ) ? $code : 301 ); 
				exit;
			}
		}

		
		
		$method = isset( $_SERVER['REQUEST_METHOD'] ) ? strtoupper( (string) $_SERVER['REQUEST_METHOD'] ) : 'GET';
		if ( is_404() && 'GET' === $method ) {
			self::log_404( $path );
		}
	}

	
	
	

	
	public static function normalize_path( $uri ) {
		$uri  = (string) $uri;
		
		
		
		$path = function_exists( 'wp_parse_url' )
			? (string) wp_parse_url( $uri, PHP_URL_PATH )
			: (string) parse_url( $uri, PHP_URL_PATH ); 
		if ( '' === $path ) {
			return '/';
		}
		$path = rawurldecode( $path );
		$path = '/' . ltrim( $path, '/' );
		if ( '/' !== $path ) {
			$path = rtrim( $path, '/' );
		}
		return '' === $path ? '/' : $path;
	}

	
	public static function match_path( $path, $rules ) {
		if ( ! is_array( $rules ) ) {
			return null;
		}
		foreach ( $rules as $r ) {
			if ( empty( $r['is_regex'] ) && isset( $r['source_path'] ) && (string) $r['source_path'] === $path ) {
				return $r;
			}
		}
		foreach ( $rules as $r ) {
			if ( ! empty( $r['is_regex'] ) && isset( $r['source_path'] ) && '' !== (string) $r['source_path'] ) {
				$re = '~' . str_replace( '~', '\\~', (string) $r['source_path'] ) . '~';
				if ( 1 === @preg_match( $re, $path ) ) {
					return $r;
				}
			}
		}
		return null;
	}

	
	public static function resolve_target( $rule, $path ) {
		$target = isset( $rule['target'] ) ? (string) $rule['target'] : '';
		if ( '' === $target ) {
			return '';
		}
		if ( ! empty( $rule['is_regex'] ) ) {
			$re       = '~' . str_replace( '~', '\\~', (string) $rule['source_path'] ) . '~';
			$replaced = @preg_replace( $re, $target, $path );
			if ( is_string( $replaced ) && '' !== $replaced ) {
				$target = $replaced;
			}
		}
		if ( preg_match( '~^https?://~i', $target ) ) {
			return $target; 
		}
		return function_exists( 'home_url' ) ? home_url( '/' . ltrim( $target, '/' ) ) : '/' . ltrim( $target, '/' );
	}

	
	
	

	
	private static function cache_ver() {
		return (string) get_option( 'aieo_seo_redirects_ver', '0' );
	}

	
	private static function lookup_exact( $path ) {
		$key    = 'rx_' . self::cache_ver() . '_' . md5( (string) $path );
		$cached = wp_cache_get( $key, self::CACHE_GROUP );
		if ( false !== $cached ) {
			return is_array( $cached ) ? $cached : null; 
		}
		global $wpdb;
		$t = $wpdb->prefix . 'aieo_seo_redirects';
		if ( ! self::table_exists( $t ) ) {
			return null; 
		}
		$row = $wpdb->get_row(
			$wpdb->prepare(
				
				"SELECT id, source_path, target, status_code, is_regex FROM `{$t}` WHERE source_path = %s AND is_regex = 0 AND enabled = 1 LIMIT 1",
				(string) $path
			),
			ARRAY_A
		);
		wp_cache_set( $key, $row ? $row : 0, self::CACHE_GROUP, HOUR_IN_SECONDS );
		return $row ? $row : null;
	}

	
	private static function load_regex_rules() {
		$ver    = self::cache_ver();
		$cached = wp_cache_get( self::REGEX_KEY, self::CACHE_GROUP );
		if ( is_array( $cached ) && isset( $cached['ver'], $cached['rows'] ) && (string) $cached['ver'] === $ver ) {
			return $cached['rows'];
		}
		global $wpdb;
		$t = $wpdb->prefix . 'aieo_seo_redirects';
		if ( ! self::table_exists( $t ) ) {
			return array();
		}
		
		$rows = $wpdb->get_results( "SELECT id, source_path, target, status_code, is_regex FROM `{$t}` WHERE is_regex = 1 AND enabled = 1 ORDER BY id ASC LIMIT 1000", ARRAY_A );
		$rows = is_array( $rows ) ? $rows : array();
		wp_cache_set( self::REGEX_KEY, array( 'ver' => $ver, 'rows' => $rows ), self::CACHE_GROUP, HOUR_IN_SECONDS );
		return $rows;
	}

	private static function record_hit( $id ) {
		$id = (int) $id;
		if ( $id <= 0 ) {
			return;
		}
		
		
		if ( function_exists( 'wp_rand' ) && 1 !== wp_rand( 1, 10 ) ) {
			return;
		}
		global $wpdb;
		$t = $wpdb->prefix . 'aieo_seo_redirects';
		
		$wpdb->query( $wpdb->prepare( "UPDATE `{$t}` SET hits = hits + 10, last_hit = %s WHERE id = %d", current_time( 'mysql', true ), $id ) );
	}

	private static function bust() {
		wp_cache_delete( self::RULES_KEY, self::CACHE_GROUP );
		
		
		if ( ! self::$dirty && function_exists( 'add_action' ) ) {
			self::$dirty = true;
			add_action( 'shutdown', array( __CLASS__, 'flush_edge_map' ), 20 );
		}
	}

	
	public static function flush_edge_map() {
		if ( self::$dirty ) {
			self::$dirty = false;
			
			
			update_option( 'aieo_seo_redirects_ver', (string) microtime( true ), true );
			self::export_edge_map();
		}
	}

	private static function table_exists( $t ) {
		global $wpdb;
		
		return (string) $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $t ) ) === $t;
	}

	private static function active() {
		$opt = get_option( 'aieo_dmm_settings' );
		return is_array( $opt ) && ! empty( $opt['seo']['enabled'] );
	}

	
	
	

	public static function log_404( $path ) {
		$path = (string) $path;
		if ( '' === $path || '/' === $path ) {
			return;
		}
		
		if ( preg_match( '~\.(?:js|css|png|jpe?g|gif|svg|webp|avif|ico|woff2?|ttf|eot|map|txt|xml|json|php|env|bak)$~i', $path ) ) {
			return;
		}
		if ( strlen( $path ) > 190 ) {
			$path = substr( $path, 0, 190 );
		}
		global $wpdb;
		$t   = $wpdb->prefix . 'aieo_seo_404_log';
		if ( ! self::table_exists( $t ) ) {
			return;
		}
		$now = current_time( 'mysql', true );
		$ref = isset( $_SERVER['HTTP_REFERER'] ) ? esc_url_raw( (string) wp_unslash( $_SERVER['HTTP_REFERER'] ) ) : '';
		
		$wpdb->query( $wpdb->prepare(
			"INSERT INTO `{$t}` (path, hits, referrer, first_seen, last_seen) VALUES (%s, 1, %s, %s, %s)
			 ON DUPLICATE KEY UPDATE hits = hits + 1, last_seen = VALUES(last_seen), referrer = VALUES(referrer)",
			$path,
			$ref,
			$now,
			$now
		) );
		
		if ( function_exists( 'wp_rand' ) && 1 === wp_rand( 1, 100 ) ) {
			self::prune_404( 2000 );
		}
	}

	private static function prune_404( $keep ) {
		global $wpdb;
		$t = $wpdb->prefix . 'aieo_seo_404_log';
		
		$cut = (int) $wpdb->get_var( $wpdb->prepare( "SELECT id FROM `{$t}` ORDER BY id DESC LIMIT %d, 1", (int) $keep ) );
		if ( $cut > 0 ) {
			
			$wpdb->query( $wpdb->prepare( "DELETE FROM `{$t}` WHERE id < %d AND redirected = 0", $cut ) );
		}
	}

	
	
	

	
	public static function add( $source, $target, $code = 301, $opts = array() ) {
		$is_regex = ! empty( $opts['is_regex'] ) ? 1 : 0;
		$enabled  = array_key_exists( 'enabled', $opts ) ? ( ! empty( $opts['enabled'] ) ? 1 : 0 ) : 1;
		$source   = (string) $source;
		if ( ! $is_regex ) {
			$source = self::normalize_path( $source );
		}
		$source = substr( $source, 0, 190 );
		$target = trim( (string) $target );
		if ( '' === $source || ( '' === $target && 410 !== (int) $code ) ) {
			return false;
		}
		$code = in_array( (int) $code, array( 301, 302, 307, 308, 410 ), true ) ? (int) $code : 301;

		global $wpdb;
		$t = $wpdb->prefix . 'aieo_seo_redirects';
		if ( ! self::table_exists( $t ) ) {
			return false;
		}

		
		
		
		
		
		
		if ( ! $is_regex && 410 !== $code && $enabled ) {
			$tnorm = self::internal_target_path( $target );
			if ( null !== $tnorm && 'loop' === self::chain_status( $source, $tnorm ) ) {
				return false;
			}
		}

		$now = current_time( 'mysql', true );
		
		$ok = $wpdb->query( $wpdb->prepare(
			"INSERT INTO `{$t}` (source_path, target, status_code, is_regex, enabled, source, created_at)
			 VALUES (%s, %s, %d, %d, %d, %s, %s)
			 ON DUPLICATE KEY UPDATE target = VALUES(target), status_code = VALUES(status_code),
			   is_regex = VALUES(is_regex), enabled = VALUES(enabled), source = VALUES(source)",
			$source,
			$target,
			$code,
			$is_regex,
			$enabled,
			isset( $opts['source'] ) ? (string) $opts['source'] : 'manual',
			$now
		) );
		
		
		if ( false !== $ok && null !== self::$chain_map && ! $is_regex ) {
			if ( $enabled ) {
				$tgt = ( 410 === $code ) ? null : self::internal_target_path( $target );
				self::$chain_map[ self::fold( $source ) ] = ( null === $tgt ) ? null : self::fold( $tgt );
			} else {
				unset( self::$chain_map[ self::fold( $source ) ] );
			}
		}
		self::bust();
		return false !== $ok;
	}

	
	
	

	
	private static $chain_map = null;

	
	private static function fold( $path ) {
		$path = (string) $path;
		return function_exists( 'mb_strtolower' ) ? mb_strtolower( $path, 'UTF-8' ) : strtolower( $path );
	}

	
	public static function source_key( $source ) {
		return self::fold( substr( self::normalize_path( (string) $source ), 0, 190 ) );
	}

	
	private static function chain_map() {
		if ( null !== self::$chain_map ) {
			return self::$chain_map;
		}
		self::$chain_map = array();
		global $wpdb;
		$t = $wpdb->prefix . 'aieo_seo_redirects';
		if ( self::table_exists( $t ) ) {
			
			foreach ( (array) $wpdb->get_results( "SELECT source_path, target, status_code FROM `{$t}` WHERE is_regex = 0 AND enabled = 1", ARRAY_A ) as $r ) {
				$tgt = ( 410 === (int) $r['status_code'] ) ? null : self::internal_target_path( (string) $r['target'] );
				self::$chain_map[ self::fold( (string) $r['source_path'] ) ] = ( null === $tgt ) ? null : self::fold( $tgt );
			}
		}
		return self::$chain_map;
	}

	
	public static function chain_status( $source, $target_path ) {
		$source      = self::fold( $source );
		$target_path = ( null === $target_path ) ? null : self::fold( $target_path );
		$map         = self::chain_map();
		$map[ $source ] = $target_path; 
		$seen           = array( $source => true );
		$hop            = $target_path;
		$depth          = 0;
		while ( $depth++ < 12 ) {
			if ( null === $hop || ! isset( $map[ $hop ] ) ) {
				return 'ok'; 
			}
			if ( isset( $seen[ $hop ] ) ) {
				return 'loop';
			}
			$seen[ $hop ] = true;
			$hop          = $map[ $hop ];
		}
		return 'loop'; 
	}

	
	public static function would_loop( $source, $target, $code = 301 ) {
		if ( 410 === (int) $code ) {
			return false;
		}
		$tnorm = self::internal_target_path( (string) $target );
		if ( null === $tnorm ) {
			return false;
		}
		
		
		return 'loop' === self::chain_status( substr( self::normalize_path( (string) $source ), 0, 190 ), $tnorm );
	}

	
	public static function target_exists( $target, $code = 301, array $assume_sources = array() ) {
		if ( 410 === (int) $code ) {
			return true;
		}
		$path = self::internal_target_path( (string) $target );
		if ( null === $path || '/' === $path ) {
			return true; 
		}
		$key = self::fold( $path );

		
		
		
		$map = self::chain_map();
		if ( isset( $map[ $key ] ) || isset( $assume_sources[ $key ] ) || isset( $assume_sources[ self::fold( substr( $path, 0, 190 ) ) ] ) ) {
			return true;
		}

		
		
		static $memo = array();
		if ( isset( $memo[ $key ] ) ) {
			return $memo[ $key ];
		}

		global $wpdb;
		$found = false;

		$sp = $wpdb->prefix . 'aieo_seo_posts';
		if ( self::table_exists( $sp ) ) {
			
			
			
			$found = (bool) $wpdb->get_var( $wpdb->prepare(
				"SELECT 1 FROM `{$sp}` WHERE canonical_url IN (%s, %s) LIMIT 1",
				$path,
				$path . '/'
			) );
		}
		if ( ! $found && function_exists( 'url_to_postid' ) && function_exists( 'home_url' ) ) {
			$found = url_to_postid( home_url( $path ) ) > 0;
		}
		if ( ! $found && function_exists( 'get_page_by_path' ) ) {
			$probe = get_page_by_path( trim( $path, '/' ) );
			$found = ( $probe instanceof WP_Post && 'publish' === $probe->post_status );
		}
		if ( ! $found ) {
			
			
			
			
			
			$slug = rawurldecode( basename( rtrim( $path, '/' ) ) );
			if ( '' !== $slug ) {
				$found = (bool) $wpdb->get_var( $wpdb->prepare(
					"SELECT 1 FROM {$wpdb->terms} t INNER JOIN {$wpdb->term_taxonomy} tt ON tt.term_id = t.term_id WHERE t.slug = %s LIMIT 1",
					$slug
				) );
			}
		}

		$memo[ $key ] = $found;
		return $found;
	}

	
	private static function internal_target_path( $target ) {
		$target = (string) $target;
		if ( preg_match( '~^https?://~i', $target ) ) {
			$host = strtolower( (string) parse_url( $target, PHP_URL_HOST ) ); 
			$site = function_exists( 'home_url' ) ? strtolower( (string) parse_url( home_url(), PHP_URL_HOST ) ) : ''; 
			if ( '' === $host || $host !== $site ) {
				return null; 
			}
		}
		return self::normalize_path( $target );
	}

	
	public static function repoint_targets( $old_path, $new_path ) {
		$old_path = (string) $old_path;
		$new_path = (string) $new_path;
		if ( '' === $old_path || $old_path === $new_path ) {
			return;
		}
		global $wpdb;
		$t = $wpdb->prefix . 'aieo_seo_redirects';
		if ( ! self::table_exists( $t ) ) {
			return;
		}
		
		
		
		
		
		$wpdb->query( $wpdb->prepare( "UPDATE `{$t}` SET target = %s WHERE is_regex = 0 AND target = %s AND source_path <> %s", $new_path, $old_path, $new_path ) );
		self::$chain_map = null; 
		self::bust();
	}

	
	public static function delete_by_source( $path ) {
		global $wpdb;
		$t    = $wpdb->prefix . 'aieo_seo_redirects';
		$norm = substr( self::normalize_path( (string) $path ), 0, 190 );
		if ( ! self::table_exists( $t ) ) {
			return;
		}
		$wpdb->delete( $t, array( 'source_path' => $norm, 'is_regex' => 0 ), array( '%s', '%d' ) );
		if ( null !== self::$chain_map ) {
			unset( self::$chain_map[ self::fold( $norm ) ] );
		}
		self::bust();
	}

	public static function delete( $id ) {
		global $wpdb;
		$t  = $wpdb->prefix . 'aieo_seo_redirects';
		$ok = $wpdb->delete( $t, array( 'id' => (int) $id ), array( '%d' ) );
		self::bust();
		return false !== $ok;
	}

	
	public static function set_enabled( $id, $enabled ) {
		global $wpdb;
		$t = $wpdb->prefix . 'aieo_seo_redirects';
		if ( $enabled ) {
			
			$row = $wpdb->get_row( $wpdb->prepare( "SELECT source_path, target, status_code, is_regex FROM `{$t}` WHERE id = %d", (int) $id ), ARRAY_A );
			if ( $row && empty( $row['is_regex'] ) && 410 !== (int) $row['status_code'] ) {
				$tnorm = self::internal_target_path( (string) $row['target'] );
				if ( null !== $tnorm && 'loop' === self::chain_status( (string) $row['source_path'], $tnorm ) ) {
					return false;
				}
			}
		}
		$wpdb->update( $t, array( 'enabled' => $enabled ? 1 : 0 ), array( 'id' => (int) $id ), array( '%d' ), array( '%d' ) );
		self::$chain_map = null; 
		self::bust();
		return true;
	}

	
	public static function all( $limit = 200, $offset = 0 ) {
		global $wpdb;
		$t = $wpdb->prefix . 'aieo_seo_redirects';
		if ( ! self::table_exists( $t ) ) {
			return array();
		}
		
		$rows = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM `{$t}` ORDER BY id DESC LIMIT %d OFFSET %d", (int) $limit, (int) $offset ), ARRAY_A );
		return is_array( $rows ) ? $rows : array();
	}

	public static function count_all() {
		global $wpdb;
		$t = $wpdb->prefix . 'aieo_seo_redirects';
		if ( ! self::table_exists( $t ) ) {
			return 0;
		}
		
		return (int) $wpdb->get_var( "SELECT COUNT(*) FROM `{$t}`" );
	}

	
	public static function top_404( $limit = 100 ) {
		global $wpdb;
		$t = $wpdb->prefix . 'aieo_seo_404_log';
		if ( ! self::table_exists( $t ) ) {
			return array();
		}
		
		$rows = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM `{$t}` WHERE redirected = 0 ORDER BY hits DESC, last_seen DESC LIMIT %d", (int) $limit ), ARRAY_A );
		return is_array( $rows ) ? $rows : array();
	}

	public static function delete_404( $id ) {
		global $wpdb;
		$wpdb->delete( $wpdb->prefix . 'aieo_seo_404_log', array( 'id' => (int) $id ), array( '%d' ) );
	}

	
	public static function mark_404_redirected( $path ) {
		global $wpdb;
		$wpdb->update( $wpdb->prefix . 'aieo_seo_404_log', array( 'redirected' => 1 ), array( 'path' => (string) $path ), array( '%d' ), array( '%s' ) );
	}

	
	public static function import_aioseo() {
		global $wpdb;
		$src = $wpdb->prefix . 'aioseo_redirects';
		$out = array( 'available' => false, 'imported' => 0, 'skipped_missing_target' => 0, 'skipped_loop' => 0, 'regex_unverified' => 0 );
		if ( ! self::table_exists( $src ) ) {
			return $out;
		}
		$out['available'] = true;
		
		$cols = array_map( 'strval', (array) $wpdb->get_col( "SHOW COLUMNS FROM `{$src}`" ) );
		$src_col = in_array( 'source_url', $cols, true ) ? 'source_url' : ( in_array( 'url', $cols, true ) ? 'url' : '' );
		$tgt_col = in_array( 'target_url', $cols, true ) ? 'target_url' : '';
		if ( '' === $src_col || '' === $tgt_col ) {
			return $out;
		}
		$has_enabled = in_array( 'enabled', $cols, true );
		
		$rows = $wpdb->get_results( "SELECT * FROM `{$src}`", ARRAY_A );

		
		
		
		$file_sources = array();
		foreach ( (array) $rows as $r ) {
			$s = isset( $r[ $src_col ] ) ? (string) $r[ $src_col ] : '';
			if ( '' !== $s && empty( $r['regex'] ) ) {
				$file_sources[ self::source_key( $s ) ] = true;
			}
		}

		foreach ( (array) $rows as $r ) {
			$source = isset( $r[ $src_col ] ) ? (string) $r[ $src_col ] : '';
			$target = isset( $r[ $tgt_col ] ) ? (string) $r[ $tgt_col ] : '';
			if ( '' === $source ) {
				continue;
			}
			$code     = isset( $r['type'] ) ? (int) $r['type'] : 301;
			$is_regex = ! empty( $r['regex'] ) ? 1 : 0;
			
			$enabled  = $has_enabled ? ( ! empty( $r['enabled'] ) ? 1 : 0 ) : 1;

			if ( $is_regex ) {
				$out['regex_unverified']++;
			} else {
				if ( ! self::target_exists( $target, $code, $file_sources ) ) {
					$out['skipped_missing_target']++;
					continue;
				}
				
				
				if ( $enabled && self::would_loop( $source, $target, $code ) ) {
					$out['skipped_loop']++;
					continue;
				}
			}

			if ( self::add( $source, $target, $code, array( 'is_regex' => $is_regex, 'enabled' => $enabled, 'source' => 'import' ) ) ) {
				$out['imported']++;
			}
		}
		return $out;
	}

	
	
	

	
	public static function edge_dir() {
		$up = wp_upload_dir();
		return trailingslashit( $up['basedir'] ) . 'aieo-redirects';
	}

	
	public static function export_edge_map() {
		global $wpdb;
		$dir = self::edge_dir();
		if ( ! wp_mkdir_p( $dir ) ) {
			return;
		}
		$t = $wpdb->prefix . 'aieo_seo_redirects';
		
		
		$rows = ( self::active() && self::table_exists( $t ) )
			
			? $wpdb->get_results( "SELECT source_path, target, status_code, is_regex FROM `{$t}` WHERE enabled = 1 ORDER BY is_regex ASC, id ASC LIMIT 50000", ARRAY_A )
			: array();

		$buckets = array( 301 => array(), 302 => array(), 307 => array(), 308 => array(), 410 => array() );
		foreach ( (array) $rows as $r ) {
			$code = (int) $r['status_code'];
			if ( ! isset( $buckets[ $code ] ) ) {
				continue;
			}
			$keys = self::map_keys( (string) $r['source_path'], ! empty( $r['is_regex'] ) );
			if ( empty( $keys ) ) {
				continue;
			}
			if ( 410 === $code ) {
				foreach ( $keys as $k ) {
					$buckets[410][] = $k . ' 1;';
				}
				continue;
			}
			$val = self::map_value( (string) $r['target'] );
			if ( '' === $val ) {
				continue;
			}
			foreach ( $keys as $k ) {
				$buckets[ $code ][] = $k . ' ' . $val . ';';
			}
		}

		foreach ( $buckets as $code => $lines ) {
			$content  = "# AIEO redirects -> {$code}. Auto-generated; do not edit.\n";
			$content .= empty( $lines ) ? "# (none)\n" : implode( "\n", $lines ) . "\n";
			self::write_atomic( $dir . '/' . $code . '.map', $content );
		}
		self::write_atomic( $dir . '/version.txt', (string) ( function_exists( 'current_time' ) ? current_time( 'timestamp', true ) : time() ) );

		
		do_action( 'aieo_seo_edge_exported' );
	}

	
	private static function map_keys( $source, $is_regex ) {
		$source = self::nginx_escape( $source );
		if ( '' === $source ) {
			return array();
		}
		if ( $is_regex ) {
			return array( '"~' . $source . '"' );
		}
		$bare = rtrim( $source, '/' );
		if ( '' === $bare ) {
			return array(); 
		}
		return array( '"' . $bare . '"', '"' . $bare . '/"' );
	}

	private static function map_value( $target ) {
		$target = self::nginx_escape( $target );
		return '' === $target ? '' : '"' . $target . '"';
	}

	
	private static function nginx_escape( $s ) {
		$s = str_replace( array( "\r", "\n" ), '', (string) $s );
		$s = str_replace( '\\', '\\\\', $s );
		$s = str_replace( '"', '\\"', $s );
		return $s;
	}

	private static function write_atomic( $path, $contents ) {
		$tmp = $path . '.' . ( function_exists( 'wp_generate_password' ) ? wp_generate_password( 6, false ) : (string) mt_rand() ) . '.tmp';
		if ( false === file_put_contents( $tmp, $contents ) ) { 
			return false;
		}
		if ( ! @rename( $tmp, $path ) ) { 
			@unlink( $tmp ); 
			return false;
		}
		return true;
	}

	
	public static function nginx_config() {
		$edge   = self::edge_dir();
		$sm_path = '/wp-content/uploads/aieo-sitemaps';
		if ( class_exists( 'AIEO_SEO_Sitemap' ) ) {
			$p = (string) wp_parse_url( AIEO_SEO_Sitemap::url(), PHP_URL_PATH );
			if ( '' !== $p ) {
				$sm_path = rtrim( $p, '/' );
			}
		}
		$lines = array(
			'# ===== AIEO edge serving (generated for this site) =====',
			'# (1) http{} context — e.g. a conf.d/*.conf include:',
			'map $uri $aieo_r301 { default ""; include ' . $edge . '/301.map; }',
			'map $uri $aieo_r302 { default ""; include ' . $edge . '/302.map; }',
			'map $uri $aieo_r307 { default ""; include ' . $edge . '/307.map; }',
			'map $uri $aieo_r308 { default ""; include ' . $edge . '/308.map; }',
			'map $uri $aieo_r410 { default ""; include ' . $edge . '/410.map; }',
			'',
			'# (2) server{} context, BEFORE the main `location /`:',
			'if ($aieo_r410) { return 410; }',
			'if ($aieo_r308) { return 308 $aieo_r308; }',
			'if ($aieo_r307) { return 307 $aieo_r307; }',
			'if ($aieo_r302) { return 302 $aieo_r302; }',
			'if ($aieo_r301) { return 301 $aieo_r301; }',
			'location = /sitemap.xml { try_files ' . $sm_path . '/sitemap.xml /index.php?$args; }',
		);
		return implode( "\n", $lines );
	}
}
