<?php
/**
 * @copyright (c) Kufer Software GmbH, Loisachstrasse 4, D-84453 Mühldorf 
 */


class Logger {
  
  static $logger;
  
  
  public static function getInstance() {
    
    if (!isset(self::$logger)) {
      self::$logger = new MaxFileSizeLogger(defined('DEBUG_FILE_SIZE') ? DEBUG_FILE_SIZE : (2 * 1024 * 1024));
      $logFilePath = ConstantOperations::getPathForLog() . 'debug.txt';
      self::$logger->setLogFilePath($logFilePath);
    }
    return self::$logger;
  }
  
  public static function logg($pMessage, $pSeverity = 0)  {
    
    $logger = Logger::getInstance();
    $logger->log($pMessage, $pSeverity);
    $logger->trimFile();
  }
  
  
  public static function loggException($pMessage, $pSeverity = 10)
  {
    $result = 'Ein Fehler ist aufgetreten: '.$pMessage->getMessage()
        .' bei '.$pMessage->getFile().':'.$pMessage->getLine()."\n"
        .'Stacktrace: '.$pMessage->getTraceAsString();
    self::logg($result, $pSeverity);
  }
  
  
  public static function getSeverity() {
    return 10; 
  }
}


class EchoLogger {

  
  public static function logg($pMessage, $pSeverity = 0) {
    if ($pSeverity >= Logger::getSeverity()) {
      echo "Schweregrad: $pSeverity : $pMessage \n";
      flush();
    } 
  }
  
}


class DateiLogger {
  
  public function __construct()
  {
    $logPath = ConstantOperations::getPathForLog();
    $this->logFilePath = $logPath.'debug.txt';
  }

  private static $instance;
  private $logFilePath;
  
  public static function getInstance() {
    if(self::$instance == null)
      self::$instance = new DateiLogger();
    return self::$instance;
  }
  
  public function getLogFilePath() {
   return $this->logFilePath;
  }
  
  public function setLogFilePath($logFilePath) {
    $this->logFilePath = $logFilePath;
  }

  public function log($pMessage, $pSeverity = 0, $showObjectsAndArraysInOneLine = false) {
    if ($pSeverity >= Logger::getSeverity()) {
      
      $logfile = $this->getLogFilePath();
        $handle = @fopen($logfile, 'a');
        if ($handle === false) 
          return;
        
        if(is_object($pMessage) || is_array($pMessage)) {
          if($showObjectsAndArraysInOneLine) {
            $pMessage = DebugOperations::getVarString($pMessage, true);
          } else {
            $pMessage = "\n".print_r($pMessage, true);
          }
        }
        
        $backtrace = debug_backtrace();
        $line = @$backtrace[1]['line'];
        $file = @pathinfo(@$backtrace[1]['file'], PATHINFO_BASENAME);
        $class = @$backtrace[2]['class'];
        $function = @$backtrace[2]['function'];
        
        fwrite($handle, date("Y.M.d H:i:s: ")."($pSeverity) message='$pMessage' file='$file' class='$class' function='$function' line='$line'\r\n");
        fclose($handle);
    }
  }

  
  public static function logg($pMessage, $pSeverity = 0, $showObjectsAndArraysInOneLine = false) {
    $dateilogger = self::getInstance();
    $dateilogger->log($pMessage, $pSeverity, $showObjectsAndArraysInOneLine);
  }
}


class DateiLoggerAnmeldung {
  
  
  public static function logg($pMessage, $pSeverity = 0) { 
    if ($pSeverity >= LoggerAnmeldung::getSeverity()) {
      
      $logPath = ConstantOperations::getPathForLog();
      $logfile = $logPath.'Anmeldelog.txt';
      if (file_exists($logPath)) {
        $handle = @fopen($logfile, 'a');
        if ($handle === false)
          return;
        fwrite($handle, date("Y.M.d H:i:s: ")." $pMessage\r\n");
        fclose($handle);
      }
    }
  }
}


class LoggerAnmeldung {
  
  
  public static function getInstance() {
    static $logger;
    if (!isset($logger))
      $logger = new DateiLoggerAnmeldung();
    return $logger;
  }
  
  public static function logg($pMessage, $pSeverity = 0)  {
    
    $logger = LoggerAnmeldung::getInstance();
    $logger->logg($pMessage, $pSeverity);
  }
  
  public static function getSeverity() {
    return 0;
  }
}


class MaxFileSizeLogger extends DateiLogger {
  
  private static $instance;
  
  
  private $maxFileSize;
  
  public function getMaxFileSize()
  {
    return $this->maxFileSize;
  }
  
  public function setMaxFileSize($pMaxFileSize)
  {
    $this->maxFileSize = $pMaxFileSize;
  }

  public function __construct($pMaxFileSize)
  {
    parent::__construct();
    if($pMaxFileSize <= 0)
      throw new Exception('$pMaxFileSize muss größer als 0 sein');
    $this->maxFileSize = $pMaxFileSize;
    $logFilePath = ConstantOperations::getPathForLog() . 'debug.txt';
    $this->setLogFilePath($logFilePath);
  }

  public static function getInstance()
  {
    if (self::$instance == null)
      self::$instance = new MaxFileSizeLogger(DEBUG_FILE_SIZE); 
    return self::$instance;
  }
  
  public static function logg($pMessage, $pSeverity = 0, $showObjectsAndArraysInOneLine = false)
  {
    $instance = self::getInstance();
    $instance->log($pMessage, $pSeverity, $showObjectsAndArraysInOneLine);
    $instance->trimFile();
  }
  
  public function trimFile() 
  {
    $logfile = $this->getLogFilePath();

    $size = filesize($logfile);
    if($size === false)
      return;

    if($size <= $this->maxFileSize)
      return;

    $overhead = $size - $this->maxFileSize;

    $filehandle = fopen($logfile, 'r+');
    if($filehandle === false)
      return;

    fseek($filehandle, $overhead, SEEK_SET);
    $content = fread($filehandle, $this->maxFileSize);
    fseek($filehandle, 0, SEEK_SET);
    ftruncate($filehandle, 0);
    fwrite($filehandle, $content);
    fclose($filehandle);
  }
  
}

class EpayLogger extends MaxFileSizeLogger {

  private static $instance;
  private $logLevel = 0;
  
  public function __construct($pMaxFileSize)
  {
    parent::__construct($pMaxFileSize);
    $epaySettings = WbPluginSettings::getInstance('epayment');
    if($epaySettings != false) {
      $this->logLevel = $epaySettings->getSetting('loglevel');
    }

    $logFilePath = ConstantOperations::getPathForLog() . 'epaydebug.txt';
    $this->setLogFilePath($logFilePath);
  }

  public static function getInstance()
  {
    if (self::$instance == null)
      self::$instance = new self(DEBUG_FILE_SIZE); 
    return self::$instance;
  }

  public function log($pMessage, $pSeverity = 0, $showObjectsAndArraysInOneLine = false) {
    if($pSeverity < $this->logLevel) {
      return;
    }

    $logfile = $this->getLogFilePath();
    $handle = @fopen($logfile, 'a');
    if ($handle === false) 
      return;
    
    if(is_object($pMessage) || is_array($pMessage)) {
      if($showObjectsAndArraysInOneLine) {
        $pMessage = DebugOperations::getVarString($pMessage, true);
      } else {
        $pMessage = "\n".print_r($pMessage, true);
      }
    }
    
    fwrite($handle, $this->getLogString($pMessage, $pSeverity));
    fclose($handle);
  }

  private function getLogString($message, $severity) {
    $backtrace = debug_backtrace();
    $line = @$backtrace[2]['line'];
    $file = @pathinfo(@$backtrace[2]['file'], PATHINFO_BASENAME);
    $class = @$backtrace[3]['class'];
    $function = @$backtrace[3]['function'];
    if($severity > 0 && $severity < 500) {
      return "[{$this->getSeverityTag($severity)}]: ".date("Y.m.d H:i:s").": $message\r\n";
    } else {
      return "[{$this->getSeverityTag($severity)}]: ".date("Y.m.d H:i:s").": $file:$class:$function at line $line: $message\r\n";
    }
  }

  private function getSeverityTag($severity) {
    if($severity < 0) {
      return "DEBUG";
    } elseif($severity < 500) {
      return "INFO";
    } elseif($severity < 1000) {
      return "WARNING";
    } elseif($severity < 5000) {
      return "ERROR";
    } elseif($severity < 10000) {
      return "SEVERE ERROR";
    } else {
      return "UNKNOWN SEVERITY";
    }
  }

  
  public static function logg($pMessage, $pSeverity = 0, $showObjectsAndArraysInOneLine = false) {
    $logger = self::getInstance();
    $logger->log($pMessage, $pSeverity, $showObjectsAndArraysInOneLine);
    $logger->trimFile();
  }
}
    
?>