#!/usr/bin/env node
/**
 * Build a WordPress.org-compliant zip of PressConduit.
 *
 * WordPress.org and the Divi Marketplace ban the same two things, so this reuses
 * the same stripping as build-marketplace.mjs:
 *   - No self-updater (WordPress.org serves updates). Excluded + gated off.
 *   - No in-plugin paid-unlock/licensing UI (Guideline 5). Excluded + gated off.
 *
 * What's WordPress.org-specific:
 *   - Ships the WordPress.org readme (bin/wporg-readme.txt) which includes the
 *     REQUIRED "External services" disclosure (the relay + the user's AI).
 *   - Sets distribution mode to 'wporg' so the admin says updates come from
 *     WordPress.org.
 *
 * RESIDUAL REVIEW RISK (not auto-fixable): the file-management tools let a
 * connected AI edit theme/plugin files. WordPress.org reviewers scrutinize this.
 * It's off by default and scoped to wp-content, but be ready to justify it.
 *
 * OUTPUT
 *   ../pressconduit-wporg-<version>.zip   (top-level folder: pressconduit/)
 *
 * USAGE
 *   node bin/build-wporg.mjs
 */
import {
	cpSync, rmSync, readFileSync, writeFileSync, existsSync, mkdirSync,
} from 'node:fs';
import { join, relative, dirname, sep } from 'node:path';
import { fileURLToPath } from 'node:url';
import { execSync } from 'node:child_process';

const __dirname = dirname( fileURLToPath( import.meta.url ) );
const PLUGIN_ROOT = join( __dirname, '..' );
const REPO_ROOT   = join( PLUGIN_ROOT, '..' );
const STAGING     = join( REPO_ROOT, '.pc-wporg-build' );
const STAGE_DIR   = join( STAGING, 'pressconduit' );

const EXCLUDE = new Set( [
	'bin',
	'docs',
	'PRICING-LICENSING-SPEC.md',
	'includes/class-pcd-pc-updater.php',         // FORBIDDEN: self-update from own API
	'includes/class-pcd-pc-license.php',         // FORBIDDEN: in-plugin licensing
	'includes/class-pcd-pc-file-ops.php',        // FORBIDDEN: writes files to wp-content
	'includes/tools/class-pcd-pc-tools-files.php',  // FORBIDDEN: arbitrary file read/write/edit
	'includes/tools/class-pcd-pc-tools-admin.php',  // FORBIDDEN: plugin/theme install + management
	'includes/tools/class-pcd-pc-tools-bricks.php', // remote doc fetch; Lite is Divi-only
	'build-distribution.php',                    // we write a fresh wporg one below
	'.git',
	'node_modules',
] );

function isExcluded( absSrc ) {
	const rel = relative( PLUGIN_ROOT, absSrc );
	if ( rel === '' ) return false;
	const top = rel.split( sep )[ 0 ];
	if ( EXCLUDE.has( rel ) || EXCLUDE.has( top ) ) return true;
	if ( rel.endsWith( '.zip' ) ) return true;
	if ( rel.endsWith( '.DS_Store' ) ) return true;
	return false;
}

const mainPhpSrc = readFileSync( join( PLUGIN_ROOT, 'pressconduit.php' ), 'utf8' );
const versionMatch = mainPhpSrc.match( /define\(\s*'PCD_PC_VERSION',\s*'([^']+)'\s*\)/ );
if ( ! versionMatch ) { console.error( 'Could not find PCD_PC_VERSION in pressconduit.php' ); process.exit( 1 ); }
const VERSION = versionMatch[ 1 ];
const OUT_ZIP = join( REPO_ROOT, `pressconduit-wporg-${ VERSION }.zip` );

if ( ! mainPhpSrc.includes( 'pcd_pc_is_direct_build' ) ) {
	console.error( 'FAIL: pressconduit.php has no distribution-mode gating. Aborting.' );
	process.exit( 1 );
}

// --- fresh staging -----------------------------------------------------------
rmSync( STAGING, { recursive: true, force: true } );
mkdirSync( STAGE_DIR, { recursive: true } );
cpSync( PLUGIN_ROOT, STAGE_DIR, { recursive: true, filter: ( src ) => ! isExcluded( src ) } );

// --- distribution marker: wporg ----------------------------------------------
writeFileSync( join( STAGE_DIR, 'build-distribution.php' ), `<?php
/**
 * WordPress.org build marker. Sets distribution mode to 'wporg', which disables
 * the self-updater and in-plugin licensing UI (both forbidden on WordPress.org).
 * The relay/direct build omits this file and defaults to 'direct'.
 */
if ( ! defined( 'ABSPATH' ) ) {
\texit;
}
if ( ! defined( 'PCD_PC_DISTRIBUTION_MODE' ) ) {
\tdefine( 'PCD_PC_DISTRIBUTION_MODE', 'wporg' );
}
` );

// --- WordPress.org readme (with required External services disclosure) --------
const readmeTemplate = join( __dirname, 'wporg-readme.txt' );
if ( ! existsSync( readmeTemplate ) ) {
	console.error( 'FAIL: bin/wporg-readme.txt is missing. Aborting.' );
	process.exit( 1 );
}
let readme = readFileSync( readmeTemplate, 'utf8' );
if ( ! readme.includes( '== External services ==' ) ) {
	console.error( 'FAIL: wporg readme is missing the External services section. Aborting.' );
	process.exit( 1 );
}
readme = readme.replace( /Stable tag:\s*.*/i, `Stable tag: ${ VERSION }` )
               .replace( /= 0\.0\.0 =/, `= ${ VERSION } =` );
writeFileSync( join( STAGE_DIR, 'readme.txt' ), readme );

// --- verify the GPLv2 license.txt carried in from the source root ------------
// license.txt lives in the plugin root (single source of truth) and is copied
// with the tree above. Guard that it landed and contains the full GPL text.
const stagedLicense = join( STAGE_DIR, 'license.txt' );
if ( ! existsSync( stagedLicense ) ) {
	console.error( 'FAIL: license.txt is missing from the source root. Aborting.' );
	process.exit( 1 );
}
if ( ! readFileSync( stagedLicense, 'utf8' ).includes( 'GNU GENERAL PUBLIC LICENSE' ) ) {
	console.error( 'FAIL: license.txt does not contain the full GPL text. Aborting.' );
	process.exit( 1 );
}

// --- safety net: forbidden files must be absent ------------------------------
for ( const forbidden of [ 'includes/class-pcd-pc-updater.php', 'includes/class-pcd-pc-license.php' ] ) {
	if ( existsSync( join( STAGE_DIR, forbidden ) ) ) {
		console.error( `FAIL: forbidden file leaked into the package: ${ forbidden }` );
		process.exit( 1 );
	}
}

// --- zip it ------------------------------------------------------------------
rmSync( OUT_ZIP, { force: true } );
execSync( `zip -rq "${ OUT_ZIP }" pressconduit -x "*.DS_Store"`, { cwd: STAGING, stdio: 'inherit' } );
rmSync( STAGING, { recursive: true, force: true } );

console.log( '' );
console.log( `Built WordPress.org package: ${ OUT_ZIP }` );
console.log( `Version: ${ VERSION }` );
console.log( 'Mode: wporg (self-update + licensing disabled and excluded)' );
console.log( 'Added: build-distribution.php (wporg), readme.txt (with External services); license.txt ships from the source root' );
console.log( 'Heads-up: be ready to justify the file-management tools in review.' );
