"""Help the user to create a new pentest database.
"""
import tkinter as tk
import tkinter.ttk as ttk
from customtkinter import *
from datetime import datetime
from pollenisatorgui.core.components import utils
from pollenisatorgui.core.forms.formpanel import FormPanel
from pollenisatorgui.core.views.viewelement import ViewElement
from pollenisatorgui.core.components.settings import Settings
from pollenisatorgui.core.components.apiclient import APIClient

class ChildDialogNewPentest(CTkToplevel):
    """
    Open a child dialog of a tkinter application to ask details about
    a new pentest database to create.
    """

    def __init__(self, parent, default):
        """
        Open a child dialog of a tkinter application to ask details about
        the new pentest.

        Args:
            parent: the tkinter parent view to use for this window construction.
        """
        super().__init__(parent)
        self.attributes("-type", "dialog")
        self.parent = parent
        self.title("Create a pentest")
        self.resizable(True, True)
        self.bind("<Escape>", self.onError)
        monitor = utils.get_screen_where_widget(parent)
        self.geometry(f"{800}x{900}+{monitor.x+(monitor.width//2)-(800//2)}+{monitor.y+(monitor.height//2)-(900//2)}")
        
        self.rvalue = None
        self.parent = parent
        mainFrame = CTkFrame(self)
        self.form = FormPanel()
        form1 = self.form.addFormPanel(grid=True, side=tk.TOP, fill=tk.X)
        form1.addFormLabel("Pentest name")
        form1.addFormStr("Pentest name", r".+", default=default.get("name", ""), column=1)
        form1.addFormLabel("Mission name",row=1)
        form1.addFormStr("Mission name", r".+", default=default.get("mission_name", ""), row=1, column=1)
        form1.addFormLabel("Client's name", row=2)
        form1.addFormStr("Client's name", r".+", default=default.get("client_name", ""), row=2, column=1)
        form1.addFormLabel("Report language", row=3)
        langs = APIClient.getInstance().getLangList()
        form1.addFormCombo("lang", langs, default=default.get("lang", "en"), row=3, column=1)
        types = list(Settings.getPentestTypes().keys())
        if types:
            form1.addFormLabel("Pentest type", row=4)
            form1.addFormCombo(
                "Pentest type", types, default=default.get("type", types[0]), row=4, column=1)
        form1.addFormLabel("Starting", row=5)
        form1.addFormDate("startd", self, default.get("start", datetime.strftime(datetime.now(), "%d/%m/%Y %H:%M:%S")), "%d/%m/%Y %H:%M:%S", row=5, column=1)
        form1.addFormLabel("Ending", row=6)
        form1.addFormDate("endd", self, default.get("end", "31/12/2099 00:00:00"),
                          "%d/%m/%Y %H:%M:%S", row=6, column=1)
        form2 = self.form.addFormPanel(grid=True, side=tk.TOP, fill=tk.X, pady=5)
        form2.addFormLabel("Scope", pady=5)
        form2.addFormText(
            "Scope", "", default.get("scope", ""),  height=100, column=1, sticky=tk.W+tk.E, pady=5)
        form2.addFormHelper(
            "You can declare network ip as IP/MASKSIZE, ips or domains", column=2, sticky=tk.W)
        form3 = self.form.addFormPanel(side=tk.TOP, fill=tk.X, pady=5)
        form3.addFormSearchBar("Pentester search", self.searchCallback, self.form, side=tk.TOP)
        form3.addFormLabel("Pentesters added", side=tk.LEFT)
        form3.addFormTreevw(
            "Additional pentesters names", ("Additional pentesters names", "added"), default.get("pentesters", ["", ""]), add_empty_row=True, width=200, pady=5, fill=tk.X, side=tk.TOP, anchor=tk.CENTER)
        form4 = self.form.addFormPanel(side=tk.TOP, fill=tk.X, pady=5)
        default_settings = []
        for key, val in default.get("settings", {}).items():
            if val == 1:
                default_settings.append(key)
        form4.addFormChecklist("Settings", ["Add domains whose IP are in scope",
                                            "Add domains who have a parent domain in scope", "Add all domains found"], default_settings, side=tk.TOP, fill=tk.X, pady=5)
        form4.addFormButton("Create", self.onOk, side=tk.BOTTOM)
        self.form.constructView(mainFrame)
        form1.setFocusOn("Database name")
        mainFrame.pack(fill=tk.BOTH, ipadx=10, ipady=10)
        try:
            self.wait_visibility()
            self.transient(parent)
            self.focus_force()
            self.grab_set()
            self.lift()
        except tk.TclError:
            pass
        self.update()

    def searchCallback(self, searchreq):
        apiclient = APIClient.getInstance()
        users = apiclient.searchUsers(searchreq)
        if users is None:
            return [], "Invalid response from API"
        ret = [{"TITLE":user, "additional pentesters names":{"text":user}} for user in users]
        return ret, ""
    
    def onError(self, _event=None):
        self.rvalue = None
        self.destroy()

    def onOk(self, _event=None):
        """
        Called when the user clicked the validation button. Set the rvalue attributes to the value selected and close the window.
        
        Args:
            _event: not used but mandatory
        """
        # send the data to the parent
        res, msg = self.form.checkForm()
        if res:
            form_values = self.form.getValue()
            form_values_as_dicts = ViewElement.list_tuple_to_dict(form_values)
            self.rvalue = {"name": form_values_as_dicts["Pentest name"],
                           "mission_name": form_values_as_dicts["Mission name"],
                           "client_name": form_values_as_dicts["Client's name"],
                           "lang": form_values_as_dicts["lang"],
                           "type": form_values_as_dicts.get("Pentest type", ""),
                           "start": form_values_as_dicts["startd"],
                           "end": form_values_as_dicts["endd"],
                           "settings": form_values_as_dicts["Settings"],
                           "scope": form_values_as_dicts["Scope"],
                           "pentesters": "\n".join([x[0] for x in form_values_as_dicts["Additional pentesters names"] if x and x[0] != ""])}
            self.destroy()
        else:
            tk.messagebox.showwarning(
                "Form not validated", msg, parent=self)
