<?php

class ConfigRouterOSNetwatchImport extends NetworkConfigItem
{
  function NetwatchImport(): void
  {
    $StartTime = time();

    // Load all interfaces to memory
    $Interfaces = array();
    $DbResult = $this->Database->select('NetworkInterface', '`Id`, `LocalIP` AS `IP`, `Online`, 0 AS `NewOnline`');
    while ($DbRow = $DbResult->fetch_assoc())
      $Interfaces[$DbRow['IP']] = $DbRow;

    // Load netwatch status from all DHCP routers
    $DbResult3 = $this->Database->query('SELECT `DHCP` FROM `NetworkSubnet` '.
      'WHERE (`Configure` = 1) AND (`DHCP` != "") GROUP BY `DHCP`');
    while ($Subnet = $DbResult3->fetch_assoc())
    {
      echo('router '.$Subnet['DHCP']."\n");
      $Routerboard = new RouterosAPI();
      $Routerboard->Connect($Subnet['DHCP'], $this->System->Config['API']['UserName'],
        $this->System->Config['API']['Password']);
      if (!$Routerboard->Connected) continue;
      $Routerboard->Write('/tool/netwatch/getall', false);
      $Routerboard->Write('=.proplist=host,status');
      $Read = $Routerboard->Read(false);
      $List = $Routerboard->ParseResponse($Read);
      foreach ($List as $Properties)
      {
        $IP = $Properties['host'];
        if ($Properties['status'] == 'up') $Online = 1;
          else $Online = 0;

        if ($Online)
        {
          if (array_key_exists($IP, $Interfaces))
            $Interfaces[$IP]['NewOnline'] = 1;
            else echo('IP '.$IP.' not found.'."\n");
        }
      }
    }

    $Queries = array();
    $QueriesInsert = array();
    foreach ($Interfaces as $Interface)
    {
      // Update last online time if still online
      if ($Interface['NewOnline'])
        $Queries[] = $this->Database->GetUpdate('NetworkInterface', '`Id` = '.$Interface['Id'],
          array('LastOnline' => TimeToMysqlDateTime($StartTime)));

      if ($Interface['Online'] != $Interface['NewOnline'])
      {
        // Online state changed
        $QueriesInsert[] = 'INSERT INTO `NetworkInterfaceUpDown` (`Interface`,'.
          '`State`, `Time`, `Previous`) VALUES ('.$Interface['Id'].', '.$Interface['NewOnline'].', "'.
          TimeToMysqlDateTime($StartTime).'", (SELECT MAX(T2.Id) FROM NetworkInterfaceUpDown AS T2 WHERE T2.Interface='.$Interface['Id'].'))';
        $Queries[] = $this->Database->GetUpdate('NetworkInterface', '`Id` = "'.$Interface['Id'].'"',
          array('Online' => $Interface['NewOnline']));
      }
    }
    echo("transakce insert\n");
    $this->Database->Transaction($QueriesInsert);
    echo("done\n");
    echo("transakce\n");
    $this->Database->Transaction($Queries);
    echo("done\n");

    // Update Duration for new items
    echo("Update Duration\n");
    $this->Database->query('UPDATE NetworkInterfaceUpDown AS T1, NetworkInterfaceUpDown AS T2 '.
      'SET T1.Duration = TIMESTAMPDIFF(SECOND, T1.Time, T2.Time) '.
      'WHERE (T2.Previous = T1.Id) AND (T2.Interface = T1.Interface) AND (T1.Duration IS NULL) AND (T2.Time = "'.TimeToMysqlDateTime($StartTime).'")');
    echo("done\n");

    // Set offline all interfaces which were not updated as online
    $DbResult = $this->Database->select('NetworkInterface', '*', '(`Online` = 1) AND '.
      '(`LastOnline` < "'.TimeToMysqlDateTime($StartTime).'")');
    while ($DbRow = $DbResult->fetch_assoc())
    {
      echo('IP '.$DbRow['LocalIP'].' online but time not updated.'."\n");
    }
    $DbResult = $this->Database->select('NetworkInterface', '*', '(`Online` = 0) AND '.
      '(`LastOnline` >= "'.TimeToMysqlDateTime($StartTime).'")');
    while ($DbRow = $DbResult->fetch_assoc())
    {
      echo('IP '.$DbRow['LocalIP'].' not online but time updated.'."\n");
    }

    $Queries = array();
    // Update device online state
    $DbResult = $this->Database->select('NetworkInterface', '`Device`, SUM(`Online`) AS `SumOnline`', '`Online` = 1 GROUP BY `Device`');
    while ($Device = $DbResult->fetch_assoc())
    {
      if ($Device['SumOnline'] > 0)
        $Queries[] = $this->Database->GetUpdate('NetworkDevice', 'Id='.$Device['Device'], array('LastOnline' => TimeToMysqlDateTime($StartTime), 'Online' => 1));
    }
    $Queries[] = $this->Database->GetUpdate('NetworkDevice', '`LastOnline` < "'.TimeToMysqlDateTime($StartTime).'"', array('Online' => 0));
    echo("Transakce 2\n");
    $this->Database->Transaction($Queries);
    echo("done\n");
  }

  function Run(): void
  {
    RepeatFunction(10, array($this, 'NetwatchImport'));
  }
}
