<?php

/**
 * Manage version display info.
 *
 * @package wp-cli
 */
class Version_Info_Command extends WP_CLI_Command {
    /**
     * Check if version info is removed.
     *
     * ## EXAMPLES
     *
     *     wp version-info is-secure
     *
     * @subcommand is-secure
     */
    public function is_secure() {
        if ( !$this->_are_readme_files_secured() || !$this->_are_themes_secured() ) {
            WP_CLI::print_value( false );
        } else {
            WP_CLI::print_value( true );
        }
    }

    /**
    * Remove version info.
    *
    * [--skip-success=<skip-success>]
    * : Skip success messages:
    *
    *    **true**: skip success messages.
    *
    * ## EXAMPLES
    *
    *     wp version-info secure
    *     wp version-info secure --skip-success=true
    */
    public function secure($_, $assoc_args) {
        $this->_secure_readme_files();
        $this->_secure_themes();
        $skipSuccess = isset($assoc_args['skip-success']) ? $assoc_args['skip-success'] : false;
        if ('true' !== $skipSuccess) {
            WP_CLI::success( "Version info was successfully removed." );
	}
    }

    /**
     * Remove version info from meta.
     *
     * ## EXAMPLES
     *
     *     wp version-info secure-themes
     *
     * @subcommand secure-themes
     */
    public function secure_themes() {
        $this->_secure_themes();
        WP_CLI::success( "Themes were successfully secured." );
    }

    /**
     * Check if readme files are secured.
     *
     * @return bool
     */
    private function _are_readme_files_secured() {
        foreach ( $this->_get_readme_filenames() as $readme_file ) {
            if (0 != filesize( $readme_file ) ) {
                return false;
            }
        }
        return true;
    }

    /**
     * Secure readme files.
     */
    private function _secure_readme_files() {
        foreach ( $this->_get_readme_filenames() as $readme_file ) {
            $this->_write_file( $readme_file, '' );
        }
    }

    /**
     * Get list of readme files.
     *
     * @return array
     */
    private function _get_readme_filenames() {
        return array_filter( array( ABSPATH . 'liesmich.html', ABSPATH . 'readme.html' ),
            function( $f ) { return file_exists( $f ); } );
    }

    /**
     * Check if themes are secured.
     *
     * @return bool
     */
    private function _are_themes_secured() {
        foreach ( wp_get_themes() as $theme ) {
            if ( !$this->_is_theme_secure( $theme ) ) {
                return false;
            }
        }
        return true;
    }

    /**
     * Check if theme is secured.
     *
     * @param WP_Theme $theme
     * @return bool
     */
    private function _is_theme_secure( $theme ) {
        // have to check in parent functions.php too (for child theme)
        $functions_filenames = array_filter(
            array( $theme->stylesheet_dir . '/functions.php', $theme->template_dir . '/functions.php' ),
            function( $f ) { return file_exists( $f ); }
        );

        foreach ( array_unique( $functions_filenames ) as $functions_file ) {
            $file_contents = $this->_read_file( $functions_file );
            if ( preg_match( '/^[\s]*remove_action[\s]*\([\s]*(\'|")wp_head(\'|")[\s]*,[\s]*(\'|")wp_generator(\'|")[\s]*\)/m',
                    $file_contents
            ) ) {
                return true;
            }
        }
        return false;
    }

    /**
     * Secure themes.
     */
    private function _secure_themes( ) {
        $remove_action_line = "remove_action('wp_head', 'wp_generator');";

        foreach ( wp_get_themes() as $theme ) {
            if ( $this->_is_theme_secure( $theme ) ) {
                continue;
            }
            $functions_file = $theme->template_dir . '/functions.php';

            if ( !file_exists( $functions_file ) ) {
                $file_contents = "<?php\n\n{$remove_action_line}\n";
                $this->_write_file( $functions_file, $file_contents, true );
            } else {
                $file_contents = $this->_read_file( $functions_file );
                $file_contents =
                    ( preg_match_all( '/<\?php/', $file_contents, $m ) == preg_match_all( '/\?>/', $file_contents, $m ) )
                        ? $file_contents . "\n<?php\n\n{$remove_action_line}\n"
                        : $file_contents . "\n{$remove_action_line}\n";
                $this->_write_file( $functions_file, $file_contents );
            }
        }
    }

    /**
     * Get contents of file.
     *
     * @param string $filename
     * @return string
     */
    private function _read_file( $filename ) {
        if ( !is_readable( $filename ) || false === ( $file_contents = file_get_contents( $filename ) ) ) {
            WP_CLI::error( "Could not read file '{$filename}'." );
        }

        return $file_contents;
    }

    /**
     * Put contents to file.
     *
     * @param string $filename
     * @param string $contents
     * @param bool $new_file
     */
    private function _write_file( $filename, $contents, $new_file = false ) {
        if ( ( !$new_file && !is_writable( $filename ) ) || false === file_put_contents( $filename, $contents ) ) {
            WP_CLI::error( "Could not write to file '{$filename}'." );
        }
    }
}

WP_CLI::add_command( 'version-info', 'Version_Info_Command' );
