<?php
/**
 * Copyright © 2008 Roan Kattouw <roan.kattouw@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 * http://www.gnu.org/copyleft/gpl.html
 *
 * @file
 */

use MediaWiki\Context\RequestContext;
use MediaWiki\Parser\Parser;
use MediaWiki\SpecialPage\SpecialPage;
use MediaWiki\User\UserFactory;
use MediaWiki\Utils\ExtensionInfo;
use Wikimedia\ParamValidator\ParamValidator;

/**
 * @ingroup API
 */
class ApiParamInfo extends ApiBase {

	private $helpFormat;

	/** @var RequestContext */
	private $context;

	/** @var UserFactory */
	private $userFactory;

	/**
	 * @param ApiMain $main
	 * @param string $action
	 * @param UserFactory $userFactory
	 */
	public function __construct(
		ApiMain $main,
		$action,
		UserFactory $userFactory
	) {
		parent::__construct( $main, $action );
		$this->userFactory = $userFactory;
	}

	public function execute() {
		// Get parameters
		$params = $this->extractRequestParams();

		$this->helpFormat = $params['helpformat'];
		$this->context = new RequestContext;
		$this->context->setUser( $this->userFactory->newAnonymous() ); // anon to avoid caching issues
		$this->context->setLanguage( $this->getMain()->getLanguage() );

		if ( is_array( $params['modules'] ) ) {
			$modules = [];
			foreach ( $params['modules'] as $path ) {
				if ( $path === '*' || $path === '**' ) {
					$path = "main+$path";
				}
				if ( str_ends_with( $path, '+*' ) || str_ends_with( $path, ' *' ) ) {
					$submodules = true;
					$path = substr( $path, 0, -2 );
					$recursive = false;
				} elseif ( str_ends_with( $path, '+**' ) || str_ends_with( $path, ' **' ) ) {
					$submodules = true;
					$path = substr( $path, 0, -3 );
					$recursive = true;
				} else {
					$submodules = false;
				}

				if ( $submodules ) {
					try {
						$module = $this->getModuleFromPath( $path );
					} catch ( ApiUsageException $ex ) {
						foreach ( $ex->getStatusValue()->getErrors() as $error ) {
							$this->addWarning( $error );
						}
						continue;
					}
					// @phan-suppress-next-next-line PhanTypeMismatchArgumentNullable,PhanPossiblyUndeclaredVariable
					// recursive is set when used
					$submodules = $this->listAllSubmodules( $module, $recursive );
					if ( $submodules ) {
						$modules = array_merge( $modules, $submodules );
					} else {
						$this->addWarning( [ 'apierror-badmodule-nosubmodules', $path ], 'badmodule' );
					}
				} else {
					$modules[] = $path;
				}
			}
		} else {
			$modules = [];
		}

		if ( is_array( $params['querymodules'] ) ) {
			$queryModules = $params['querymodules'];
			foreach ( $queryModules as $m ) {
				$modules[] = 'query+' . $m;
			}
		} else {
			$queryModules = [];
		}

		if ( is_array( $params['formatmodules'] ) ) {
			$formatModules = $params['formatmodules'];
			foreach ( $formatModules as $m ) {
				$modules[] = $m;
			}
		} else {
			$formatModules = [];
		}

		$modules = array_unique( $modules );

		$res = [];

		foreach ( $modules as $m ) {
			try {
				$module = $this->getModuleFromPath( $m );
			} catch ( ApiUsageException $ex ) {
				foreach ( $ex->getStatusValue()->getErrors() as $error ) {
					$this->addWarning( $error );
				}
				continue;
			}
			$key = 'modules';

			// Back compat
			$isBCQuery = false;
			if ( $module->getParent() && $module->getParent()->getModuleName() == 'query' &&
				in_array( $module->getModuleName(), $queryModules )
			) {
				$isBCQuery = true;
				$key = 'querymodules';
			}
			if ( in_array( $module->getModuleName(), $formatModules ) ) {
				$key = 'formatmodules';
			}

			$item = $this->getModuleInfo( $module );
			if ( $isBCQuery ) {
				$item['querytype'] = $item['group'];
			}
			$res[$key][] = $item;
		}

		$result = $this->getResult();
		$result->addValue( [ $this->getModuleName() ], 'helpformat', $this->helpFormat );

		foreach ( $res as $key => $stuff ) {
			ApiResult::setIndexedTagName( $res[$key], 'module' );
		}

		if ( $params['mainmodule'] ) {
			$res['mainmodule'] = $this->getModuleInfo( $this->getMain() );
		}

		if ( $params['pagesetmodule'] ) {
			$pageSet = new ApiPageSet( $this->getMain()->getModuleManager()->getModule( 'query' ) );
			$res['pagesetmodule'] = $this->getModuleInfo( $pageSet );
			unset( $res['pagesetmodule']['name'] );
			unset( $res['pagesetmodule']['path'] );
			unset( $res['pagesetmodule']['group'] );
		}

		$result->addValue( null, $this->getModuleName(), $res );
	}

	/**
	 * List all submodules of a module
	 * @param ApiBase $module
	 * @param bool $recursive
	 * @return string[]
	 */
	private function listAllSubmodules( ApiBase $module, $recursive ) {
		$paths = [];
		$manager = $module->getModuleManager();
		if ( $manager ) {
			$names = $manager->getNames();
			sort( $names );
			foreach ( $names as $name ) {
				$submodule = $manager->getModule( $name );
				$paths[] = $submodule->getModulePath();
				if ( $recursive && $submodule->getModuleManager() ) {
					$paths = array_merge( $paths, $this->listAllSubmodules( $submodule, $recursive ) );
				}
			}
		}
		return $paths;
	}

	/**
	 * @param array &$res Result array
	 * @param string $key Result key
	 * @param Message[] $msgs
	 * @param bool $joinLists
	 */
	protected function formatHelpMessages( array &$res, $key, array $msgs, $joinLists = false ) {
		switch ( $this->helpFormat ) {
			case 'none':
				break;

			case 'wikitext':
				$ret = [];
				foreach ( $msgs as $m ) {
					$ret[] = $m->setContext( $this->context )->text();
				}
				$res[$key] = implode( "\n\n", $ret );
				if ( $joinLists ) {
					$res[$key] = preg_replace( '!^(([*#:;])[^\n]*)\n\n(?=\2)!m', "$1\n", $res[$key] );
				}
				break;

			case 'html':
				$ret = [];
				foreach ( $msgs as $m ) {
					$ret[] = $m->setContext( $this->context )->parseAsBlock();
				}
				$ret = implode( "\n", $ret );
				if ( $joinLists ) {
					$ret = preg_replace( '!\s*</([oud]l)>\s*<\1>\s*!', "\n", $ret );
				}
				$res[$key] = Parser::stripOuterParagraph( $ret );
				break;

			case 'raw':
				$res[$key] = [];
				foreach ( $msgs as $m ) {
					$a = [
						'key' => $m->getKey(),
						'params' => $m->getParams(),
					];
					ApiResult::setIndexedTagName( $a['params'], 'param' );
					if ( $m instanceof ApiHelpParamValueMessage ) {
						$a['forvalue'] = $m->getParamValue();
					}
					$res[$key][] = $a;
				}
				ApiResult::setIndexedTagName( $res[$key], 'msg' );
				break;
		}
	}

	/**
	 * @param ApiBase $module
	 * @return array
	 */
	private function getModuleInfo( $module ) {
		$ret = [];
		$path = $module->getModulePath();
		$paramValidator = $module->getMain()->getParamValidator();

		$ret['name'] = $module->getModuleName();
		$ret['classname'] = get_class( $module );
		$ret['path'] = $path;
		if ( !$module->isMain() ) {
			$ret['group'] = $module->getParent()->getModuleManager()->getModuleGroup(
				$module->getModuleName()
			);
		}
		$ret['prefix'] = $module->getModulePrefix();

		$sourceInfo = $module->getModuleSourceInfo();
		if ( $sourceInfo ) {
			$ret['source'] = $sourceInfo['name'];
			if ( isset( $sourceInfo['namemsg'] ) ) {
				$ret['sourcename'] = $this->context->msg( $sourceInfo['namemsg'] )->text();
			} else {
				$ret['sourcename'] = $ret['source'];
			}

			$link = SpecialPage::getTitleFor( 'Version', 'License/' . $sourceInfo['name'] )->getFullURL();
			if ( isset( $sourceInfo['license-name'] ) ) {
				$ret['licensetag'] = $sourceInfo['license-name'];
				$ret['licenselink'] = (string)$link;
			} elseif ( ExtensionInfo::getLicenseFileNames( dirname( $sourceInfo['path'] ) ) ) {
				$ret['licenselink'] = (string)$link;
			}
		}

		$this->formatHelpMessages( $ret, 'description', $module->getFinalDescription() );

		foreach ( $module->getHelpFlags() as $flag ) {
			$ret[$flag] = true;
		}

		$ret['helpurls'] = (array)$module->getHelpUrls();
		if ( isset( $ret['helpurls'][0] ) && $ret['helpurls'][0] === false ) {
			$ret['helpurls'] = [];
		}
		// @phan-suppress-next-line PhanTypePossiblyInvalidDimOffset False positive
		ApiResult::setIndexedTagName( $ret['helpurls'], 'helpurl' );

		if ( $this->helpFormat !== 'none' ) {
			$ret['examples'] = [];
			$examples = $module->getExamplesMessages();
			foreach ( $examples as $qs => $msg ) {
				$item = [
					'query' => $qs
				];
				$msg = ApiBase::makeMessage( $msg, $this->context, [
					$module->getModulePrefix(),
					$module->getModuleName(),
					$module->getModulePath()
				] );
				$this->formatHelpMessages( $item, 'description', [ $msg ] );
				if ( isset( $item['description'] ) ) {
					if ( is_array( $item['description'] ) ) {
						$item['description'] = $item['description'][0];
					} else {
						ApiResult::setSubelementsList( $item, 'description' );
					}
				}
				$ret['examples'][] = $item;
			}
			ApiResult::setIndexedTagName( $ret['examples'], 'example' );
		}

		$ret['parameters'] = [];
		$ret['templatedparameters'] = [];
		$params = $module->getFinalParams( ApiBase::GET_VALUES_FOR_HELP );
		$paramDesc = $module->getFinalParamDescription();
		$index = 0;
		foreach ( $params as $name => $settings ) {
			$settings = $paramValidator->normalizeSettings( $settings );

			$item = [
				'index' => ++$index,
				'name' => $name,
			];

			if ( !empty( $settings[ApiBase::PARAM_TEMPLATE_VARS] ) ) {
				$item['templatevars'] = $settings[ApiBase::PARAM_TEMPLATE_VARS];
				ApiResult::setIndexedTagName( $item['templatevars'], 'var' );
			}

			if ( isset( $paramDesc[$name] ) ) {
				$this->formatHelpMessages( $item, 'description', $paramDesc[$name], true );
			}

			foreach ( $paramValidator->getParamInfo( $module, $name, $settings, [] ) as $k => $v ) {
				$item[$k] = $v;
			}

			if ( $name === 'token' && $module->needsToken() ) {
				$item['tokentype'] = $module->needsToken();
			}

			if ( $item['type'] === 'NULL' ) {
				// Munge "NULL" to "string" for historical reasons
				$item['type'] = 'string';
			} elseif ( is_array( $item['type'] ) ) {
				// Set indexed tag name, for historical reasons
				ApiResult::setIndexedTagName( $item['type'], 't' );
			}

			if ( !empty( $settings[ApiBase::PARAM_HELP_MSG_INFO] ) ) {
				$item['info'] = [];
				foreach ( $settings[ApiBase::PARAM_HELP_MSG_INFO] as $i ) {
					$tag = array_shift( $i );
					$info = [
						'name' => $tag,
					];
					if ( count( $i ) ) {
						$info['values'] = $i;
						ApiResult::setIndexedTagName( $info['values'], 'v' );
					}
					$this->formatHelpMessages( $info, 'text', [
						$this->context->msg( "apihelp-{$path}-paraminfo-{$tag}" )
							->numParams( count( $i ) )
							->params( $this->context->getLanguage()->commaList( $i ) )
							->params( $module->getModulePrefix() )
					] );
					ApiResult::setSubelementsList( $info, 'text' );
					$item['info'][] = $info;
				}
				ApiResult::setIndexedTagName( $item['info'], 'i' );
			}

			$key = empty( $settings[ApiBase::PARAM_TEMPLATE_VARS] ) ? 'parameters' : 'templatedparameters';
			$ret[$key][] = $item;
		}
		ApiResult::setIndexedTagName( $ret['parameters'], 'param' );
		ApiResult::setIndexedTagName( $ret['templatedparameters'], 'param' );

		$dynamicParams = $module->dynamicParameterDocumentation();
		if ( $dynamicParams !== null ) {
			if ( $this->helpFormat === 'none' ) {
				$ret['dynamicparameters'] = true;
			} else {
				$dynamicParams = ApiBase::makeMessage( $dynamicParams, $this->context, [
					$module->getModulePrefix(),
					$module->getModuleName(),
					$module->getModulePath()
				] );
				$this->formatHelpMessages( $ret, 'dynamicparameters', [ $dynamicParams ] );
			}
		}

		return $ret;
	}

	public function isReadMode() {
		return false;
	}

	public function getAllowedParams() {
		// back compat
		$querymodules = $this->getMain()->getModuleManager()
			->getModule( 'query' )->getModuleManager()->getNames();
		sort( $querymodules );
		$formatmodules = $this->getMain()->getModuleManager()->getNames( 'format' );
		sort( $formatmodules );

		return [
			'modules' => [
				ParamValidator::PARAM_ISMULTI => true,
			],
			'helpformat' => [
				ParamValidator::PARAM_DEFAULT => 'none',
				ParamValidator::PARAM_TYPE => [ 'html', 'wikitext', 'raw', 'none' ],
			],

			'querymodules' => [
				ParamValidator::PARAM_DEPRECATED => true,
				ParamValidator::PARAM_ISMULTI => true,
				ParamValidator::PARAM_TYPE => $querymodules,
			],
			'mainmodule' => [
				ParamValidator::PARAM_DEPRECATED => true,
			],
			'pagesetmodule' => [
				ParamValidator::PARAM_DEPRECATED => true,
			],
			'formatmodules' => [
				ParamValidator::PARAM_DEPRECATED => true,
				ParamValidator::PARAM_ISMULTI => true,
				ParamValidator::PARAM_TYPE => $formatmodules,
			]
		];
	}

	protected function getExamplesMessages() {
		return [
			'action=paraminfo&modules=parse|phpfm|query%2Ballpages|query%2Bsiteinfo'
				=> 'apihelp-paraminfo-example-1',
			'action=paraminfo&modules=query%2B*'
				=> 'apihelp-paraminfo-example-2',
		];
	}

	public function getHelpUrls() {
		return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Parameter_information';
	}
}
