<?php

/**
 * @version     backend/classes/integrity.php 2015-02-21 14:15:00 UTC pav
 * @authorUrl   https://watchful.li
 * @copyright   Copyright (c) 2012-2015 watchful.li
 * @license     GNU/GPL v3 or later
 * @copyright   Copyright (c) 2012-2015 watchful.li
 * @license     GNU/GPL v3 or later
 */
defined('_JEXEC') or die('Restricted access');

class WatchfulliIntegrity extends WatchfulliAuditProcess
{

    /**
     * Compare the hashes of the core files
     * @param int $start
     * @param int $limit
     * @return \stdClass
     */
    public function auditJoomlaCoreIntegrity($start)
    {
        $helper = new WatchfulliHelper();
        $data = $this->cache->call(array('WatchfulliConnection', 'getHash'));
        $current = $start;

        $result = new stdClass();
        $result->wrong = array(); // files with wrong checksums
        $result->missing = array(); // files missing 
        $result->skipped = array(); // files skipped 
        $result->size = count($data);
        $result->start = $start;
            
        while ($this->haveTime() && $current < count($data))
        {
            //for ($current = $start; $current < $max; $current++)

            $file_path = $data[$current][0];
            $file_hash = $data[$current][1];
            $full_path = JPATH_SITE . '/' . $file_path;

            $status = $this->checkIntegrityFile($full_path, $file_hash, $helper->getMemoryLimitInBytes());

            if ($status <> 'ok')
            {
                array_push($result->$status, $file_path);
            }
            $current++;
        }

        $result->lastFileChecked = $file_path;
        $result->end = $current;

        return $result;
    }

    /**
     * Compare the md5 hash of a file with a reference
     * 
     * @param string $full_path
     * @param string $file_hash
     * @param int $memory_limit
     * @return string
     */
    private function checkIntegrityFile($full_path, $file_hash, $memory_limit)
    {
        if (!file_exists($full_path))
        {
            return 'missing';
        }

        $memory_usage = memory_get_usage();
        $file_size = filesize($full_path);

        // let's hope the file can be read
        $memoryNeeded = $memory_usage + $file_size;
        if ($memoryNeeded > $memory_limit)
        {
            return 'skipped';
        }

        // does this file have a wrong checksum ?
        if (md5_file($full_path) != $file_hash)
        {
            return 'wrong';
        }

        return 'ok';
    }
}