<?php

namespace App\Http\Controllers;

use App\Virtual;
use App\Server;
use App\System;
use Illuminate\Http\Request;
use App\Role;
use App\User;
use Gate;
use App\Jobs\NotifyMe;
use Session;

class VirtualController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
    }

    public function index()
    {
        if (Gate::allows('manage-virtuals')) {
            $virtuals= Virtual::All();

            return view('virtuals.index')->with([
                'virtuals' => $virtuals
            ]);
        }
        return redirect('/home');
    }

    public function show(virtual $virtual)
    {
        if (Gate::allows('manage-virtuals')) {
        $servers = Server::where('id', $virtual->server_id)->first();

        if ($servers==null) {
            $servers = new \App\server();
            $servers->ip="0.0.0.0";
        }

        return view('virtuals.show')->with([
            'virtual' => $virtual,
            'servers' => $servers->ip
        ]);        }
        return redirect('/home');
    }

    private function getNetwork($server)
    {
        $tmp = exec("ping -n 1 -w 1 $server->ip");
        
        //Change for use of private keys
        //$usekey="-i $server->private";
        $usekey="";

        if(!strpos($tmp, "100% loss")){
                if($server->type=="ESXi") {
                    $portgroups=$server->scripts."/portgroups.sh";
                    $tmp = exec("ssh $usekey -oNumberOfPasswordPrompts=0 root@$server->ip [ -f $portgroups ] && echo Found || echo Not");
                    if ($tmp == "Found") {
                        $switchs = exec("ssh $usekey root@$server->ip $portgroups");
                        $switchs = explode(', ', $switchs);
                        array_shift($switchs);
                    } else {
                        $switchs=["Script not found"];
                    }    
                } else {
                    $switches=$server->scripts."\getcount.ps1";
                    $tmp = exec("ssh $usekey -oNumberOfPasswordPrompts=0 administrator@$server->ip powershell.exe Test-Path $switches && echo Found || echo Not");                                  
                    if ($tmp == "Not")
                    {   
                        $switchs=["Script not found"];
                    } else { 
                        $count = Shell_Exec("ssh $usekey -oNumberOfPasswordPrompts=0 administrator@$server->ip powershell.exe $switches");
                        if ($count==1) {
                            $tmp=$server->scripts."/getname.ps1";
                            $switchs=array(Shell_Exec("ssh $usekey -oNumberOfPasswordPrompts=0 administrator@$server->ip powershell.exe $tmp one"));
                        } else {
                            if ($count>1) {
                                $tmp=$server->scripts."/getname.ps1";
                                $switchs=array(str_replace("\n","",Shell_Exec("ssh $usekey -oNumberOfPasswordPrompts=0 administrator@$server->ip powershell.exe $tmp 0"))); 
                                for ($i = 1; $i < $count; $i++) {
                                    array_push($switchs,str_replace("\n","",Shell_Exec("ssh $usekey -oNumberOfPasswordPrompts=0 administrator@$server->ip powershell.exe $tmp $i")));
                                }
                            } else {
                                $switchs=["No network available"];
                            }
                        }
                    }
                }
            } else{
                $switchs=["Server offline"];
            }
        return $switchs;
    }

    public function create()
    {
        $systems = System::All();   

        return view('virtuals.create')->with([
            'systems' => $systems
        ]);
        return view('virtuals.create');
    }

    public function store(virtual $virtual)
    {
        $data = request()->validate([
            'memory' => 'required|min:1',
            'cpu' => 'required|min:1',
            'disk' => 'required|min:1',
        ]);

        $user = auth()->user();  

        $vir = new \App\virtual();
        $vir->system = request('system');
        $vir->user_id = $user->id;
        $vir->user_name = $user->name;        
        $vir->ready = 0;

        $vir->memory= request('memory');
        $vir->disk= request('disk');
        $vir->cpu= request('cpu');
        $vir->switch= "Network not set";        
        $vir->server_id=0;
        $virtualDouble = Virtual::where([
            ['user_id', '=', $user->id],
            ['system', '=', $vir->system],
        ])->get();

        if ($virtualDouble->isNotEmpty()) {
            return redirect()->route('home');
        } 

        $vir->save();
        return redirect()->route('home');
    }

    public function editserver(Virtual $virtual) {
        if (Gate::allows('manage-virtuals')) {
            $servers = Server::All();

            return view('virtuals.editserver')->with([
                'servers' => $servers,
                'virtual' => $virtual
            ]);
        }
        return redirect('/home');
    }

    public function edit(Virtual $virtual)
    {
        if ($virtual->ready>2) {
            return redirect('/home');
        }
        $systems = System::All();
        $servers = Server::All();
  
        if ($virtual->server_id!=0) {
            $server = Server::where('id', $virtual->server_id)->first()->ip;
        } else
            $server = "0.0.0.0";

        $switch = $virtual->switch;
        return view('virtuals.edit')->with([
            'virtual' => $virtual,
            'systems' => $systems,
            'server' => $server,
            'switch' => $switch
        ]);
    }

    public function updateserver()
    {
        if (Gate::allows('manage-virtuals')) {
            $systems = System::All();
            $servers = Server::All();
    
            if ($virtual->server_id!=0) {
                $server = Server::where('id', $virtual->server_id)->first()->ip;
            } else
                $server = "0.0.0.0";

            $switch = $virtual->switch;
            return view('virtuals.edit')->with([
                'virtual' => $virtual,
                'systems' => $systems,
                'server' => $server,
                'switch' => $switch
            ]);
            }
        return redirect('/home');
    }

    public function setnetwork(Request $request, Virtual $virtual) 
    {
        if (Gate::allows('manage-virtuals')) {
            $server = Server::where('ip', $request->newserver)->first();

            $tmp = exec("ping -n 1 -w 1 $server->ip");
            if(!strpos($tmp, "100% loss")){
                $switchs = VirtualController::getNetwork($server);
                $state="Online";
            } else {
                $switchs=["Server offline"];
                $state="Offline";
            }
            return view('virtuals.setnetwork')->with([
                'virtual' => $virtual,
                'server' => $request->newserver,
                'switchs' => $switchs,
                'state' => $state,
            ]);
        }
        return redirect('/home');
    }

    
    public function storenetwork(Request $request, Virtual $virtual)  {
        if (Gate::allows('manage-virtuals')) {

            Virtual::where('id', $virtual->id)->first()
                ->update(['switch' => $request->switch]);
            Virtual::where('id', $virtual->id)->first()
                ->update(['server_id' => Server::where('ip', $request->newserver)->first()->id]);
            return redirect("/virtuals/$virtual->id");
        }
        return redirect('/home');
    }
    

    public function update(Request $request, Virtual $virtual)
    {
        $data = request()->validate([
            'memory' => 'required|min:1',
            'cpu' => 'required|min:1',
            'disk' => 'required|min:1',
        ]);

        Virtual::where('id', $virtual->id)->first()
            ->update(['system' => $request->system]);
        Virtual::where('id', $virtual->id)->first()
            ->update(['memory' => $request->memory]);
        Virtual::where('id', $virtual->id)->first()
            ->update(['disk' => $request->disk]);
        Virtual::where('id', $virtual->id)->first()
            ->update(['cpu' => $request->cpu]);        

        return redirect()->route('virtuals.index');
    }

    public function destroy(Virtual $virtual)
    {
        $virtual->delete();

        return redirect()->back();
    }

    public function allow(Virtual $virtual)
    {
        if (Gate::allows('manage-virtuals')) {

            if ($virtual->server_id==0) {
                return redirect("/virtuals/{$virtual->id}/editserver");
            }
            Virtual::where('id', $virtual->id)->first()
                ->update(['ready' => '1']);

            return redirect()->back();
        }
        return redirect('/home');
    }

    public function cancel(Virtual $virtual)
    {
        if (Gate::allows('manage-virtuals')) {
            Virtual::where('id', $virtual->id)->first()
                ->update(['ready' => '0']);
            return redirect()->back();
        }
        return redirect('/home');
    }
    
    public function requestdelete(Virtual $virtual) {
        Virtual::where('id', $virtual->id)->first()
        ->update(['ready' => '3']);
        return redirect()->back();
    }

    public function canceldelete(Virtual $virtual) {
        Virtual::where('id', $virtual->id)->first()
        ->update(['ready' => '2']);
        return redirect()->back();
    }

    public function delete(Virtual $virtual) {
        Virtual::where('id', $virtual->id)->first()
        ->update(['ready' => '4']);
        return redirect()->back();
    }

    public function find()
    {
        $q=request('q');
        $state=request('state');
        
        if(!isset($state)) {
            $virtuals = Virtual::where('user_name','LIKE','%'.$q.'%')
                                ->orWhere('system','LIKE','%'.$q.'%')
                                ->get();
        } else {
            foreach ($state as $stat) {
                $tmp = Virtual::where([
                                    ['user_name','LIKE','%'.$q.'%'],
                                    ['ready','=',$stat]])                                
                            ->orWhere([
                                    ['system','LIKE','%'.$q.'%'],
                                    ['ready','=',$stat]])
                            ->get();
                    if (isset($virtuals)) {
                        $virtuals=$virtuals->merge($tmp);
                    } else {
                        $virtuals=$tmp;
                    }
                }
        }
        if(count($virtuals) >= 0)
            return view('virtuals.index')->with([
                'virtuals' => $virtuals
            ]);        
                
        return redirect()->back();
    }
}
