from django.shortcuts import render
from django.urls import reverse
from django.http import HttpResponse,HttpResponseRedirect
from django.conf import settings
from django.views.decorators.csrf import csrf_exempt
import nmap
from django.utils import timezone
import re
import json

@csrf_exempt
def ip_home(request):
    # Check if form is submitted
    if request.method == "POST":
        ip_address = request.POST["ip_address"]
        ip_from = None
        ip_to = None

        # Check if ip_port_from and ip_port_to is in request.POST dict.
        if "ip_port_from" in request.POST:
            # if ip_port_from is '' (empty string (default)) then set it to none.
            if request.POST["ip_port_from"] == '':
                ip_from = None
            # else set it to specified value.
            else:
                ip_from = request.POST["ip_port_from"]


        if "ip_port_to" in request.POST:
            # if ip_port_to is '' (empty string (default)) then set it to none.
            if request.POST["ip_port_to"] == '':
                ip_to = None
            # else set it to specified value.
            else:
                ip_to = request.POST["ip_port_to"]


        port_scanner = nmap.PortScanner()
        if ip_to is None:
            if ip_from is None:
                # if ip_from and ip_to are None then scan the give ip address only.
                x = port_scanner.scan(ip_address,arguments=' -sV')

            else:
                # if ip_to are None then scan the give ip address and port.
                x = port_scanner.scan(ip_address,str(ip_from),arguments=' -sV')

        else:

            x = port_scanner.scan(str(ip_address),"{0}-{1}".format(ip_from,ip_to),arguments=' -sV')

        file_name,info = save_in_txt(x,ip_address)
        request.session["info"] = info
        print(port_scanner.command_line())
        #Get file_name and pass it as context so that you can download it via link.
        return HttpResponseRedirect(reverse("detail",args=(file_name,)))

        # return render(request,"ip_search.html",{"file_name":file_name+".txt","ip":ip_address})

    return render(request,"ip_search.html")



def show_detail(request,file_name):
    info = request.session["info"] if "info" in request.session else {}
    #print(info)
    file = open(settings.STATICFILES_DIRS[0]+"/"+file_name+".txt","r").read()
    a = []
    for i in file.splitlines():
        a.append(i.replace("\t",""))

    return render(request,"detail.html",{"file_name":file_name+".txt","ports":info["ports"],"ip_info":info["ip_info"]})


def save_(request,):
    request.session['IP'] = f'{request.GET.get("ip")}'
    request.session['port'] = request.GET.get('port')

    return HttpResponseRedirect('/exploit/'+request.GET.get('name')+'/')


def save_in_txt(ip_info,ip_address):
    # specify the file_name to save info. I used file name as current timestamp so that no two file has same name.
    # if you have your own method the let me know.
    file_name = re.sub('[\W_]+', '', str(timezone.now()))
    info = {"hosts":[],"ports":[]}

    with open(settings.STATICFILES_DIRS[0]+"/"+file_name+".txt","w") as file:
        # Write ip address, method, services, uphosts, downhosts, totalhosts to file.
        file.write("Ip address: "+ip_address+"\n")
        file.write("Method: "+ip_info["nmap"]["scaninfo"]["tcp"]["method"]+"\n")
        file.write("Services: "+ip_info["nmap"]["scaninfo"]["tcp"]["services"]+"\n")
        file.write("Uphosts: "+ip_info["nmap"]["scanstats"]["uphosts"]+"\n")
        file.write("Downhosts: "+ip_info["nmap"]["scanstats"]["downhosts"]+"\n")
        file.write("Totalhosts: "+ip_info["nmap"]["scanstats"]["totalhosts"]+"\n")

        info["ip_info"] = [ip_address,ip_info["nmap"]["scaninfo"]["tcp"]["method"],ip_info["nmap"]["scaninfo"]["tcp"]["services"].split(","),ip_info["nmap"]["scanstats"]["uphosts"],ip_info["nmap"]["scanstats"]["downhosts"],ip_info["nmap"]["scanstats"]["totalhosts"]]

        # Check if ip address exists in dict ( It won't exist if it shows downhosts=1 and uphosts=0)
        if ip_address in ip_info["scan"]:
            # Loop throug hostnames and write them in file.
            for hosts in ip_info["scan"][ip_address]["hostnames"]:
                file.write("Hostname: "+hosts["name"]+"\n")
                file.write("Type: "+hosts["type"]+"\n")

                info["hosts"].append([hosts["name"],hosts["type"]])

            # Write status, reason, and all the TCPs to the file.
            file.write("Status: "+ip_info["scan"][ip_address]["status"]["state"]+"\n")
            file.write("Reason: "+ip_info["scan"][ip_address]["status"]["reason"]+"\n")
            for key,item in ip_info["scan"][ip_address]["tcp"].items():
                #Write open ports, their states, reasons, names etc info to file.
                info["ports"].append([str(key),item["state"],item["reason"],item["name"],"-" if item["product"]=='' else item["product"],"-" if item["version"]=='' else item["version"]])
                file.write("\nPORT: "+str(key)+"\n\tSTATE: "+item["state"]+"\n\tREASON: "+item["reason"]+"\n\tNAME:"+item["name"]+"\n\tPRODUCT: "+item["product"]+"\n\tVERSION: "+item["version"])

        #close and save file in static folder
        file.close()

    #return file_name
    return file_name,info


    # These were some print statements for debugging.


    # print("Ip address:",ip_address)
    # print("Method:",ip_info["nmap"]["scaninfo"]["tcp"]["method"])
    # print("Services:",ip_info["nmap"]["scaninfo"]["tcp"]["services"])
    # print("Uphosts:",ip_info["nmap"]["scanstats"]["uphosts"])
    # print("Downhosts:",ip_info["nmap"]["scanstats"]["downhosts"])
    # print("Totalhosts:",ip_info["nmap"]["scanstats"]["totalhosts"])
    #
    # if ip_address in ip_info["scan"]:
    #     # print("IP:",ip_info["scan"][ip_address])
    #     for hosts in ip_info["scan"][ip_address]["hostnames"]:
    #         print("Hostname",hosts["name"])
    #         print("Type",hosts["type"])
    #
    #     print("Status:",ip_info["scan"][ip_address]["status"]["state"])
    #     print("Reason:",ip_info["scan"][ip_address]["status"]["reason"])
    #
    #     for key,item in ip_info["scan"][ip_address]["tcp"].items():
    #         print("PORT:",key," STATE:",item["state"]," REASON",item["reason"]," NAME:",item["name"]," PRODUCT",item["product"])
