<?php

/**
 * Log selected action in database with ip, datetime and optional logged user.
 * @author valentin carruesco
 * @category Core
 * @license MIT
 */

class Log extends Entity {
    public $id,$label,$category,$ip;
    public $entityLabel = 'Journaux';
    protected $fields =
    array(
        'id' => array('label'=>'Identifiant', 'type'=>'key'),
        'label' => array('label'=>'Libellé', 'type'=>'wysiwyg'),
        'category' => array('label'=>'Catégorie', 'type'=>'text'),
        'ip' => array('label'=>'Ip publique', 'type'=>'text')
    );

    public function label(){
        return preg_replace_callback('|^\[([^\]]*)\](.*)|i', function($matches){
            return '<span class="badge badge-info">'.$matches[1].'</span>'.$matches[2];
        }, $this->label);
    }

    public static function put($label,$category = 'Général') {

        $log = new self();
        $log->label = $label;
        $log->category = $category;
        $log->ip = ip();
        $log->save();
    }

    //Compare deux instances d'une même entité et log
    //les differences entre les deux dans un format JSON
    public static function compare($old,$new = null,$metafunction=null){
        $log = new self();
        $log->label = array();

        if(!isset($new) || !isset($old->id) || $old->id==0){
            $log->label['action'] = 'create';
            $log->label['fields'] = is_object($new) ? $new->toArray(): $old->toArray();
        }else if (!$new){
            $log->label['action'] = 'delete';
            $log->label['fields'] = $old->toArray();
        }elseif (is_object($new)){
            $log->label['action'] = 'update';
            $log->label['fields'] = Entity::compare($old,$new);
        }

        $log->label['entity'] = $old->tableName();
        $log->category = $log->label['entity'].'::compare';
        $log->ip = ip();

        if(isset($metafunction)) $metafunction($log);

        $log->label = json_encode($log->label);
        $log->save();
    }

    public static function clear($delay = 1){
       $treshold = time() - ($delay * 86400);
       self::delete(array('created:<'=>$treshold));
    }

    //Fonction permettant un benchmark simple et précis.
    public static function benchmark($title = ""){
        global $lastBench;
        $start = microtime(true);
        $benfile = __DIR__.SLASH.'..'.SLASH.'benchmark.debug.log';
        $bt =  debug_backtrace();

        $newBench = array(
            'time' =>  microtime(true),
            'file' =>  str_replace(__ROOT__,'',$bt[0]['file']),
            'line' =>  $bt[0]['line'],
        );

        $label = '';
        if(!isset($lastBench)){
            $label .= PHP_EOL.PHP_EOL.'['.($title=="" ? "BENCHMARK" : $title ).'] - Début requete > benchmark : '. number_format(microtime(true)-$_SERVER["REQUEST_TIME_FLOAT"],4).' ms'.PHP_EOL;
            $label .= PHP_EOL."\t".'=> '.$newBench['file'].PHP_EOL.PHP_EOL;
        } else {
            if($lastBench['file']!= $newBench['file'])  $label .= PHP_EOL."\t".'=> '.$newBench['file'].PHP_EOL;
            $time = $newBench['time'] - $lastBench['time'];
            $title.= ' L.'.$lastBench['line'].' > L.'.$newBench['line'].' '.$title;
            if($time>0.500) $title.=' <!> LENTEUR !!';
            $label .= "\t\t".number_format($time,4).' ms | '.$title.PHP_EOL;
        }

        file_put_contents($benfile, $label,FILE_APPEND);
        //on enleve au benchmark le temps d'execution de la fonciton de benchmark elle meme
        $newBench['time'] = $newBench['time'] - ( microtime(true) - $start);
        $lastBench = $newBench;
    }
}