<?php

use Monolog\Logger;
use Monolog\Handler\StreamHandler;

/*
 * Check for scheduled posts
 * Usage:
 *
 *  * Cron job need to exist on server for anything to happen:
 1 * * * * www-data cd /mnt/persist/www/xxx.se/current/web && /usr/local/bin/wp webien-scheduling run > /dev/null
 *
// * wp webien-scheduling run
 * wp webien-scheduling run --verbose
 *
*/


class Scheduling extends WP_CLI_Command
{

    private $log;

    public $dryRun = true;
    private $verbose = false;

    public function run($args, $assoc_args)
    {

        $arguments = wp_parse_args(
            $assoc_args, []
        );
        if ( isset($arguments['verbose']) ) {
            $this->verbose = true;
        }

        // create a log channel
        $this->log = new Logger('Scheduling');
        $this->log->pushHandler(new StreamHandler(WP_CONTENT_DIR . '/webien.log'));

        // Start by getting all public post types, which can be scheduled
        $post_types = get_post_types();
        $excludePostTypes = ['attachment'];
        $postTypes = array_diff($post_types, $excludePostTypes);

        $args = [
            'post_type' => $postTypes,
            'post_status' => ['publish','draft'],
            'numberposts' => -1,
            'fields' => 'ids',
            'meta_query' => [
                'relation' => 'OR',
                [
                    'key' => 'webien_schedule_start',
                    'compare' => 'EXISTS',
                ],
                [
                    'key' => 'webien_schedule_stop',
                    'compare' => 'EXISTS',
                ]
            ],
        ];
        $posts = new WP_Query($args);

        if($this->verbose){
            WP_CLI::line( 'Server clock: ' . date('H:i', time()) );
            WP_CLI::line( 'Post types: ' . implode(',', $postTypes) );
            WP_CLI::line( 'Found ' . $posts->found_posts . ' posts with scheduled meta' );
            WP_CLI::line( 'Posts: ' . implode(',', $posts->posts) );
        }


        foreach ($posts->posts as $id){
            $this->checkPost($id);
        }

        $this->log->info('All posts checked');

        if($this->verbose){
            WP_CLI::line( 'Was something updated? ' . ($this->dryRun ? 'No' : 'Yes'));
            WP_CLI::success( 'Done' );
        }

        // If something was published or unbublished, flush cache
        if(!$this->dryRun){
            $this->log->info('Scheduling updates found - Flushing all cache');
            $this->flushCache();
        }

    }



    function checkPost($id){
        $start = get_post_meta($id, 'webien_schedule_start', true);
        $stop = get_post_meta($id, 'webien_schedule_stop', true);

        $start = empty($start) ? 0 : $start;
        $stop = empty($stop) ? 0 : $stop;

        $startUnix = strtotime($start);
        $stopUnix = strtotime($stop);

        $offset = 0;
        $schedulingOffset = get_option('options_webien_scheduling_offset', 1);
        if($schedulingOffset) $offset = (int)$schedulingOffset * 3600;

        $now = time() + $offset;

        // Look for posts that should be published and has not passed the stop date
        if($startUnix && $startUnix < $now){
            if($stopUnix){
                if($stopUnix > $now){
                    $this->publishPost($id);
                }
            } else {
                $this->publishPost($id);
            }
        }

        // Look for posts that should be unpublished and has passed the stop date
        if($stopUnix && $stopUnix < $now){
            $this->unpublishPost($id);
        }


    }

    function publishPost($id){
        $status = get_post_status($id);
        if($status !== 'publish'){
            if($this->verbose) {
                WP_CLI::line('Publishing: ' . $id);
            }

            $this->dryRun = false;

            wp_update_post([
                'ID' => $id,
                'post_status' => 'publish'
            ]);
        }
    }


    function unpublishPost($id){
        $status = get_post_status($id);
        if($status === 'publish'){
            if($this->verbose) {
                WP_CLI::line('Unpublishing: ' . $id);
            }

            $this->dryRun = false;

            wp_update_post([
                'ID' => $id,
                'post_status' => 'draft'
            ]);
        }
    }


    function flushCache() {
        // Flush cache on entire site since posts can be in lists etc.
        // Since scheduling is not a common thing, we can flush all cache
        if (function_exists('run_litespeed_cache')) {
            do_action( 'litespeed_purge_all' );
        } else if (function_exists('rocket_clean_domain')) {
            rocket_clean_domain();
        } else if (is_plugin_active('nginx-helper/nginx-helper.php')) {
            global $nginx_purger;
            $nginx_purger->purge_all();
        }
    }


}

WP_CLI::add_command('webien-scheduling', 'Scheduling');