<?php
/**
 * @package Polylang-Pro
 */

/**
 * PO file, generated from exporting Polylang translations
 *
 * Handles the construction of a PO files.
 *
 * @since 2.7
 */
class PLL_PO_Export implements PLL_Export_File_Interface {

	/**
	 * Po object.
	 *
	 * @var PO
	 */
	private $po;

	/**
	 * The registered source_language
	 *
	 * @var string
	 */
	private $source_language;

	/**
	 * The registered target languages
	 *
	 * @var string
	 */
	private $target_language;

	/**
	 * PLL_Export_Interface constructor.
	 * Creates a PO object.
	 *
	 * @since 2.7
	 */
	public function __construct() {
		require_once ABSPATH . '/wp-includes/pomo/po.php';
		$this->po = new PO();
	}

	/**
	 *
	 * Set a source language to the export
	 *
	 * @since 2.7
	 *
	 * @param string $source_language Locale.
	 */
	public function set_source_language( $source_language ) {
		$this->source_language = $source_language;
		$this->po->set_header( 'Language-Source', $source_language );
	}

	/**
	 * Set a target language to the export
	 *
	 * @param string $target_language Target language.
	 *
	 * @since 2.7
	 */
	public function set_target_language( $target_language ) {
		$this->target_language = $target_language;
		$this->po->set_header( 'Language-Target', $target_language );
	}

	/**
	 * Set the site reference to the export.
	 *
	 * @since 2.7
	 *
	 * @param string $url Absolute url of the current site.
	 */
	public function set_site_reference( $url ) {
		$this->po->set_header( 'Site-Reference', $url );

	}

	/**
	 * Add a translation source and target to the current translation file
	 *
	 * @since 2.7
	 *
	 * @param string $type   Describe what does this data corresponds to, such as a post title, a meta reference etc...
	 * @param string $source The source to be translated.
	 * @param string $target Optional, preexisting translation, if any.
	 * @param array  $args   Optional, an array containing the name and the context of the string.
	 */
	public function add_translation_entry( $type, $source, $target = '', $args = array() ) {
		$entry = new Translation_Entry(
			array(
				'singular'           => $source,
				'translations'       => array( $target ),
				'context'            => isset( $args['context'] ) ? $args['context'] : null,
				'extracted_comments' => isset( $args['id'] ) ? $args['id'] : '',
			)
		);

		$this->po->add_entry( $entry );
	}

	/**
	 * Assign a reference to the PO file.
	 *
	 * @since 2.7
	 *
	 * @param string $type Type of data to be exported, @see PLL_Export_File_Interface .
	 * @param string $id   Optional, unique identifier to retrieve the data in the database.
	 */
	public function set_source_reference( $type, $id = '' ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
		$this->po->set_header( 'Source-Reference', $type );
	}

	/**
	 * Writes the file in the output buffer
	 *
	 * @since 2.7
	 */
	public function export() {
		$this->po->set_comment_before_headers( $this->get_comment_before_headers() );

		$this->set_file_headers();

		return $this->po->export();
	}

	/**
	 * Assigns the necessary headers to the PO file.
	 *
	 * @see https://www.gnu.org/software/trans-coord/manual/gnun/html_node/PO-Header.html
	 *
	 * @since 2.7
	 */
	protected function set_file_headers() {
		$this->po->set_header( 'Content-Type', 'text/plain; charset=utf-8' );
		$this->po->set_header( 'Content-Transfer-Encoding', '8bit' );
		$this->po->set_header( 'Project-Id-Version', 'POLYLANG_EXPORT' );
		$this->po->set_header( 'POT-Creation-Date', current_time( 'Y-m-d H:iO', true ) );
		$this->po->set_header( 'PO-Revision-Date', current_time( 'Y-m-d H:iO', true ) );
		$this->po->set_header( 'Last-Translator', '' );
		$this->po->set_header( 'MIME-Version', '1.0' );
	}

	/**
	 *
	 * Get the necessary text comment to add to the PO file.
	 *
	 * @return string
	 */
	protected function get_comment_before_headers() {
		$po = 'This file was generated by ' . POLYLANG . PHP_EOL;
		$po .= 'https://polylang.pro/' . PHP_EOL;

		return $po;
	}

	/**
	 * Returns the name of the file to export.
	 *
	 * @since 2.7
	 *
	 * @return string
	 */
	public function get_filename() {
		return $this->source_language . '_' . $this->target_language . '.po';
	}
}
