<?php

class ModuleLog extends AppModule
{
  function __construct(System $System)
  {
    parent::__construct($System);
    $this->Name = 'Log';
    $this->Version = '1.0';
    $this->Creator = 'Chronos';
    $this->License = 'GNU/GPLv3';
    $this->Description = 'Logging user actions';
    $this->Dependencies = array('User', 'RSS');
  }

  function DoInstall(): void
  {
  }

  function DoUnInstall(): void
  {
  }

  function DoStart(): void
  {
    $this->System->FormManager->RegisterClass('Log', array(
      'Title' => 'Záznamy',
      'Table' => 'Log',
      'DefaultSortColumn' => 'Time',
      'DefaultSortOrder' => 1,
      'Items' => array(
        'Time' => array('Type' => 'DateTime', 'Caption' => 'Čas', 'Default' => '', 'ReadOnly' => true),
        'User' => array('Type' => 'TUser', 'Caption' => 'Uživatel', 'Default' => '', 'Null' => true, 'ReadOnly' => true),
        'Module' => array('Type' => 'String', 'Caption' => 'Modul', 'Default' => '', 'ReadOnly' => true),
        'Operation' => array('Type' => 'String', 'Caption' => 'Operace', 'Default' => '', 'ReadOnly' => true),
        'Value' => array('Type' => 'Text', 'Caption' => 'Hodnota', 'Default' => '', 'ReadOnly' => true),
        'IPAddress' => array('Type' => 'IPv4Address', 'Caption' => 'Adresa IP', 'Default' => '', 'ReadOnly' => true),
      ),
    ));
    ModuleRSS::Cast($this->System->GetModule('RSS'))->RegisterRSS(array('Title' => 'Logs',
      'Channel' => 'log', 'Callback' => array($this, 'ShowRSS'),
      'Permission' => array('Module' => 'Log', 'Operation' => 'RSS')));
  }

  function DoStop(): void
  {
  }

  function NewRecord(string $Module, string $Operation, string $Value = ''): void
  {
    if ($this->System->ModuleManager->ModulePresent('User') and
      array_key_exists('Id', ModuleUser::Cast($this->System->GetModule('User'))->User->User))
      $UserId = ModuleUser::Cast($this->System->GetModule('User'))->User->User['Id'];
      else $UserId = NULL;
    if (array_key_exists('REMOTE_ADDR', $_SERVER)) $IPAddress = $_SERVER['REMOTE_ADDR'];
      else $IPAddress = '';
    $this->Database->insert('Log', array('Time' => 'NOW()',
      'User' => $UserId, 'Module' => $Module,
      'Operation' => $Operation, 'Value' => $Value, 'IPAddress' => $IPAddress));
  }

  function ShowRSS(): string
  {
    $this->ClearPage = true;
    $this->FormatHTML = false;
    Header('Content-Type: text/xml');
    $Count = 100;

    $Output = '';
    $Items = array();
    if (array_key_exists('type', $_GET)) $Where = ' WHERE `Type` = "'.($_GET['type'] * 1).'"';
      else $Where = '';
    $sql = 'SELECT *, UNIX_TIMESTAMP(`Time`) AS `TimeCreate`, (SELECT `User`.`Name` FROM `User` WHERE `User`.`Id` = `Log`.`User`) AS `UserName`, `Time` FROM `Log`'.
      $Where.' ORDER BY `Time` DESC LIMIT '.$Count;
    $DbResult = $this->System->Database->query($sql);
    while ($Line = $DbResult->fetch_assoc())
    {
      $Line['Value'] = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $Line['Value']);
      $Line['Value'] = htmlspecialchars($Line['Value']);
      $Line['Value'] = str_replace("\n", '<br>', $Line['Value']);

      $Items[] = array
      (
        'Title' => $Line['Module'].' '.$Line['Operation'].' ('.$Line['UserName'].', '.$Line['IPAddress'].')',
        'Link' => 'http://'.$this->System->Config['Web']['Host'].$this->System->Link('/log.php'),
        'Description' => $Line['Module'].' '.$Line['Operation'].': '.$Line['Value'].' ('.$Line['UserName'].
          ', '.$Line['IPAddress'].', '.HumanDate($Line['Time']).')',
        'Time' => $Line['TimeCreate'],
      );
    }

    $RSS = new RSS();
    $RSS->Title = $this->System->Config['Web']['Title'].' - Záznamy';
    $RSS->Link = 'http://'.$this->System->Config['Web']['Host'].'/';
    $RSS->Description = 'Aktuality '.$this->System->Config['Web']['Description'];
    $RSS->WebmasterEmail = $this->System->Config['Web']['AdminEmail'];
    $RSS->Items = $Items;
    return $RSS->Generate();
  }

  static function Cast(AppModule $AppModule): ModuleLog
  {
    if ($AppModule instanceof ModuleLog)
    {
      return $AppModule;
    }
    throw new Exception('Expected ModuleLog type but got '.gettype($AppModule));
  }
}
