<?php
/**
 * Piwik - Open source web analytics
 *
 * @link    http://piwik.org
 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
 */

use Piwik\Access;
use Piwik\Date;
use Piwik\Plugins\SitesManager\API;

/**
 * Tests to call the archive.php cron script and check there is no error,
 * Then call the API testing for "Browser archiving is disabled" (see disableArchiving)
 * This tests that, when archiving is disabled,
 *  then Piwik API will return data that was pre-processed during archive.php run
 *
 */
class Test_Piwik_Integration_ArchiveCronTest extends IntegrationTestCase
{
    public static $fixture = null; // initialized below class definition

    public static function createAccessInstance()
    {
        Access::setSingletonInstance($access = new Test_Access_OverrideLogin());
        \Piwik\Piwik::postEvent('Request.initAuthenticationObject');
    }

    public function getApiForTesting()
    {
        $results = array();

        // First, API calls for Segmented reports
        // Disabling these tests as they randomly fail... This could actually be a bug.
        // FIXME - I have failed finding the cause for these test to randomly fail
        // eg.
//        foreach (self::$fixture->getDefaultSegments() as $segmentName => $info) {
//            $results[] = array('VisitsSummary.get', array('idSite'     => 'all',
//                                                          'date'       => '2012-08-09',
//                                                          'periods'    => array('day', 'week', 'month', 'year'),
//                                                          'segment'    => $info['definition'],
//                                                          'testSuffix' => '_' . $segmentName));
//
//
//        }


        // API Call Without segments
        // TODO uncomment week and year period
        $results[] = array('VisitsSummary.get', array('idSite'  => 'all',
                                                      'date'    => '2012-08-09',
                                                      'periods' => array('day', 'month', /* 'year',  'week' */)));

        $results[] = array('VisitsSummary.get', array('idSite'     => 'all',
                                                      'date'       => '2012-08-09',
                                                      'periods'    => array('day', 'week', 'month', 'year'),
                                                      'segment'    => 'browserCode==EP',
                                                      'testSuffix' => '_nonPreArchivedSegment'));

        $segments = array(Test_Piwik_Fixture_ManySitesImportedLogs::SEGMENT_PRE_ARCHIVED,
                          Test_Piwik_Fixture_ManySitesImportedLogs::SEGMENT_PRE_ARCHIVED_CONTAINS_ENCODED
        );
        foreach($segments as $segment) {
            // TODO debugging travis
            continue;

            // Test with a pre-processed segment
            $results[] = array(array('VisitsSummary.get', 'Live.getLastVisitsDetails', 'VisitFrequency.get'),
                               array('idSite'     => '1',
                                     'date'       => '2012-08-09',
                                     'periods'    => array('day', 'year'),
                                     'segment'    => $segment,
                                     'testSuffix' => '_preArchivedSegment'));
        }


        return $results;
    }

    /**
     * @group        Integration
     */
    public function testArchivePhpCron()
    {
        self::deleteArchiveTables();

        $this->setLastRunArchiveOptions();
        $output = $this->runArchivePhpCron();

        foreach ($this->getApiForTesting() as $testInfo) {

            list($api, $params) = $testInfo;

            if (!isset($params['testSuffix'])) {
                $params['testSuffix'] = '';
            }
            $params['testSuffix'] .= '_noOptions';
            $params['disableArchiving'] = true;

            $success = $this->runApiTests($api, $params);

            if (!$success) {
                var_dump($output);
            }
        }
    }

    private function setLastRunArchiveOptions()
    {
        $periodTypes = array('day', 'periods');
        $idSites = API::getInstance()->getAllSitesId();

        $daysAgoArchiveRanSuccessfully = 1500;
        $this->assertTrue($daysAgoArchiveRanSuccessfully > (\Piwik\CronArchive::ARCHIVE_SITES_WITH_TRAFFIC_SINCE / 86400));
        $time = Date::factory(self::$fixture->dateTime)->subDay($daysAgoArchiveRanSuccessfully)->getTimestamp();

        foreach ($periodTypes as $period) {
            foreach ($idSites as $idSite) {
                // lastRunKey() function inlined
                $lastRunArchiveOption = "lastRunArchive" . $period . "_" . $idSite;
                \Piwik\Option::set($lastRunArchiveOption, $time);
            }
        }
    }

    private function runArchivePhpCron()
    {
        $archivePhpScript = PIWIK_INCLUDE_PATH . '/tests/PHPUnit/proxy/archive.php';
        $urlToProxy = Fixture::getRootUrl() . 'tests/PHPUnit/proxy/index.php';

        // create the command
        $cmd = "php \"$archivePhpScript\" --url=\"$urlToProxy\" 2>&1";

        // run the command
        exec($cmd, $output, $result);
        if ($result !== 0 || stripos($result, "error")) {
            throw new Exception("archive cron failed: " . implode("\n", $output) . "\n\ncommand used: $cmd");
        }

        return $output;
    }
}

Test_Piwik_Integration_ArchiveCronTest::$fixture = new Test_Piwik_Fixture_ManySitesImportedLogs();
Test_Piwik_Integration_ArchiveCronTest::$fixture->addSegments = true;