<?php

class ipNetwork
{
    private $db;
    private $collection;
    public $cidr;
    public $networks = null;
    public $wgdevice;

    public function __construct($cidr, $wgdevice)
    {
        $this->cidr = $cidr;
        $this->wgdevice = $wgdevice;
        $this->db = new database();
        $this->collection = $this->db->getMongodb("vpn")->networks;
        $this->networks = $this->getNetwork();
    }

    public function getNetwork()
    {
        if(!$this->networks){
            $filter = ['cidr' => $this->cidr, 'wgdevice' => $this->wgdevice];
            $this->networks = $this->collection->findOne($filter);
            $this->db->getArray($this->networks);
            return $this->networks;
        }else{
            return $this->networks;
        }
    }

    public function constructnetworkfile()
    {
        $ip_file = $this->getNetworkFilePath();
        $cmd = 'nmap -sL -n ' . $this->cidr . ' | awk \'/Nmap scan report/{print $NF}\'>' . $ip_file;
        return system($cmd);
    }


    public function getNetworkFilePath()
    {
        $file_name = str_replace('.', '_', $this->cidr);
        $file_name = str_replace('/', '_', $file_name . '_' . $this->wgdevice);
        return $_SERVER['DOCUMENT_ROOT'] . "/api/networks/" . $file_name;
    }

    public function syncNetworkFile()
    {
        if (file_exists($this->getNetworkFilePath())) {
            $data = file_get_contents($this->getNetworkFilePath());
            $data = explode(PHP_EOL, $data);
            $data = array_slice($data, 2);
            $document = array();
            $id = 0;
            foreach ($data as $ip) {
                if (empty($ip)) {
                    continue;
                }
                $val = [
                    '_id' => $id++,
                    'cidr' => $this->cidr,
                    'ip_addr' => $ip,
                    'wgdevice' => $this->wgdevice,
                    'allocated' => false,
                    'owner' => '',
                    'creation_time' => time(),
                    'allocation_time' => '',
                    'public_key' => '',
                    'private_key' => ''
                ];
                array_push($document, $val);
            }

            return $this->collection->insertMany($document);
        } else {
            throw new Exception("Fail to read the file");
        }
    }

    public function getNextIp()
    {
        $val = $this->collection->findOne(
            [
                'allocated' => false,
                'wgdevice' => $this->wgdevice
            ],
            [
                'sort' => [
                    'id' => 1
                ]
            ]
        );
        return $val['ip_addr'];
    }

    public function allocateIp($ip, $owner, $publickey)
    {
        try {
            $this->collection->updateOne([
                'ip_addr' => $ip,
                'wgdevice' => $this->wgdevice
            ], [
                '$set' => [
                    'allocated' => true,
                    'owner' => $owner,
                    'allocation_time' => time(),
                    'public_key' => $publickey

                ]
            ]);
            return true;
        } catch (Exception $e) {
            return false;
        }
    }
    //resume from here - allocate unique key only

    public function deallocate($public)
    {
        try {
            $this->collection->updateOne([
                'public_key' => $public,
                'wgdevice' => $this->wgdevice
            ], [
                '$set' => [
                    'allocated' => false,
                    'owner' => "",
                    'allocation_time' => "",
                    'public_key' => ""

                ]
            ]);
            return true;
        } catch (Exception $e) {
            return false;
        } 
    }

    public function generateIdFromCidr() {}

    public function getIp($ip) {} //function stubs

    public function getUser($ip) {}
}