#!/usr/bin/env python
# -*- coding: utf-8 -*-
#///////////////////////////////////////////////////////////////////////////////
#// Copyright (c) 2000-2019 Ericsson Telecom AB Telecom AB                               //
#//                                                                           //
#// All rights reserved. This program and the accompanying materials          //
#// are made available under the terms of the Eclipse Public License v2.0     //
#// which accompanies this distribution, and is available at                  //
#// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html                                 //
#///////////////////////////////////////////////////////////////////////////////

import re
from BaseTestCase import *
from Framework_CommonFunctions import *
from selenium.webdriver.support.color import Color
from selenium.webdriver import ActionChains

def init(driver, HTML_FILE):
    driver.get(HTML_FILE)
    startRequestTester(driver)

def loadSetup(driver, setupName):
    radioId = "RequestConsole_Dialog_LoadSetup_RadioButton_" + setupName
    loadButton = driver.wait.until(EC.element_to_be_clickable((By.ID, 'RequestConsole_Button_Load')))
    loadButton.click()
    radioButton = driver.find_element_by_id(radioId)
    radioButton.click()
    dialogClickOk(driver, "LoadSetup")
    time.sleep(1)

def dialogClickOk(driver, name):
    buttonId = "RequestConsole_Dialog_" + name + "_OkButton"
    button = driver.wait.until(EC.element_to_be_clickable((By.ID, buttonId)))
    button.click()

def getSetupName(driver):
    label = driver.find_element_by_id("RequestConsole_SetupNameLabel")
    return label.text

def treeExists(driver, id):
    try:
        div = driver.find_element_by_id(id)
        div.find_element_by_class_name("jstree-node")
        return True
    except NoSuchElementException as e:
        return False

def newSetup(driver):
    button = driver.wait.until(EC.element_to_be_clickable((By.ID, 'RequestConsole_Button_ClearRequest')))
    button.click()
    time.sleep(0.5)

def addEmptyRequest(driver):
    button = driver.wait.until(EC.element_to_be_clickable((By.ID,'RequestConsole_Button_AddRequest')))
    button.click()
    time.sleep(0.25)

def sendRequest(driver):
    button = driver.wait.until(EC.element_to_be_clickable((By.ID, 'RequestConsole_Button_Send')))
    button.click()
    time.sleep(0.25)

def editorTypeExists(driver, className):
    try:
        driver.find_element_by_class_name(className)
        return True
    except NoSuchElementException as e:
        return False

class RequestConsole_SetupHandlingTests(BaseTestCase):
    def test_loadSetup_FromConfigAtStart(self):
        init(self.driver, self.HTML_FILE)
        setupName = getSetupName(self.driver)

        self.driver.implicitly_wait(0.5)

        self.assertEqual(setupName, "Test1", "Displayed setup name is incorrect, it is " + setupName + " and it should be: Test1")
        self.assertTrue(treeExists(self.driver, "RequestConsole_HelpTree"), "There is no help tree, but it must always exist")
        self.assertTrue(treeExists(self.driver, "RequestConsole_RequestTree"), "There is no request tree, but there should be")

    def test_loadSetup_ViaDialog(self):
        init(self.driver, self.HTML_FILE)
        loadSetup(self.driver, "Test2")
        setupName = getSetupName(self.driver)

        self.driver.implicitly_wait(0.5)

        self.assertEqual(setupName, "Test2", "Displayed setup name is incorrect, it is " + setupName + " and it should be: Test2")
        self.assertTrue(treeExists(self.driver, "RequestConsole_HelpTree"), "There is no help tree, but it must always exist")
        self.assertTrue(treeExists(self.driver, "RequestConsole_RequestTree"), "There is no request tree, but there should be")

    def test_elementEditor_addEmptyRequest(self):
        init(self.driver, self.HTML_FILE)
        newSetup(self.driver)

        addEmptyRequest(self.driver)
        self.assertTrue(editorTypeExists(self.driver, "JSONEditor"), "ElementEditor element not found after clicking the addEmptyRequest button")

        closeButton = self.driver.wait.until(EC.element_to_be_clickable((By.ID, 'RequestConsole_ElementEditor_Close')))
        closeButton.click()

        self.assertTrue(treeExists(self.driver, "RequestConsole_RequestTree"), "There is no request tree, but there should be after adding an empty request")

    def test_requestEditorTree_dragAtomicRequestWithinTheRequestObject(self):
        init(self.driver, self.HTML_FILE)

        treeElements = self.driver.find_elements_by_xpath("//*[contains(@id, '_anchor')]") #for elem in treeElements: print elem.get_attribute('innerHTML')
        ActionChains(self.driver).drag_and_drop(treeElements[7], treeElements[8]).perform()
        script = "code_editor = $('#RequestConsole_CodeEditor .CodeMirror')[0].CodeMirror; return code_editor.getValue();"
        textInEditor = self.driver.execute_script(script)
        expectedString = '[\n\
    {\n\
        "getData": {\n\
            "source": "ExecCtrl",\n\
            "element": "EntityGroups",\n\
            "children": [\n\
                {\n\
                    "getData": {\n\
                        "source": "ExecCtrl",\n\
                        "element": "Clients"\n\
                    }\n\
                },\n\
                {\n\
                    "getData": {\n\
                        "source": "ExecCtrl",\n\
                        "element": "EGrpType",\n\
                        "params": [\n\
                            {\n\
                                "paramName": "EntityGroup",\n\
                                "paramValue": "%Parent0%"\n\
                            }\n\
                        ]\n\
                    }\n\
                },\n\
                {\n\
                    "getData": {\n\
                        "source": "ExecCtrl",\n\
                        "element": "EGrpSize",\n\
                        "params": [\n\
                            {\n\
                                "paramName": "EntityGroup",\n\
                                "paramValue": "%Parent0%"\n\
                            }\n\
                        ]\n\
                    }\n\
                }\n\
            ]\n\
        }\n\
    }\n\
]'
        self.assertEqual(expectedString, textInEditor, "RequestEditor\'s content is not changed correctly after an inside drag and drop")

    def test_requestEditorTree_dragRequestFromHelpTree(self):
        init(self.driver, self.HTML_FILE)

        treeElements = self.driver.find_elements_by_xpath("//*[contains(@id, '_anchor')]")

        ActionChains(self.driver).double_click(treeElements[0]).perform()

        treeElementsAfterExpand = self.driver.find_elements_by_xpath("//*[contains(@id, '_anchor')]")

        ActionChains(self.driver).drag_and_drop(treeElementsAfterExpand[1], treeElements[8]).perform()
        script = "code_editor = $('#RequestConsole_CodeEditor .CodeMirror')[0].CodeMirror; return code_editor.getValue();"
        textInEditor = self.driver.execute_script(script)
        expectedString = '[\n\
    {\n\
        "getData": {\n\
            "source": "ExecCtrl",\n\
            "element": "Clients"\n\
        }\n\
    },\n\
    {\n\
        "getData": {\n\
            "source": "ExecCtrl",\n\
            "element": "EntityGroups",\n\
            "children": [\n\
                {\n\
                    "getData": {\n\
                        "source": "DataSource",\n\
                        "element": "Sources"\n\
                    }\n\
                },\n\
                {\n\
                    "getData": {\n\
                        "source": "ExecCtrl",\n\
                        "element": "EGrpType",\n\
                        "params": [\n\
                            {\n\
                                "paramName": "EntityGroup",\n\
                                "paramValue": "%Parent0%"\n\
                            }\n\
                        ]\n\
                    }\n\
                },\n\
                {\n\
                    "getData": {\n\
                        "source": "ExecCtrl",\n\
                        "element": "EGrpSize",\n\
                        "params": [\n\
                            {\n\
                                "paramName": "EntityGroup",\n\
                                "paramValue": "%Parent0%"\n\
                            }\n\
                        ]\n\
                    }\n\
                }\n\
            ]\n\
        }\n\
    }\n\
]'
        self.assertEqual(expectedString, textInEditor, "RequestEditor\'s content is not changed correctly after dragging a request from help tree")

    def test_requestEditor_addEmptyRequest(self):
        init(self.driver, self.HTML_FILE)

        newSetup(self.driver);
        addEmptyRequest(self.driver);

        script = "code_editor = $('#RequestConsole_CodeEditor .CodeMirror')[0].CodeMirror; return code_editor.getValue();"
        textInEditor = self.driver.execute_script(script)
        expectedString = '[\n\
    {\n\
        "getData": {\n\
            "source": "Source",\n\
            "element": "Element"\n\
        }\n\
    }\n\
]'
        self.assertEqual(expectedString, textInEditor, "RequestEditor's content is not an empty request as it should be")

    def test_requestEditor_normalBorder_addEmptyRequest(self):
        init(self.driver, self.HTML_FILE)

        newSetup(self.driver);
        addEmptyRequest(self.driver);

        editorHeader = self.driver.find_element_by_id("RequestConsole_CodeEditor__Header")
        editorHeaderColor = editorHeader.value_of_css_property("color")
        self.assertEqual('#000000', str(Color.from_string(editorHeaderColor).hex), 'RequestEditor\'s header should be black, it is ' + str(Color.from_string(editorHeaderColor).hex))

    def test_requestEditor_normalBorder_settingValidRequest(self):
        init(self.driver, self.HTML_FILE)

        request = '[{"getData": {"source": "Source","element": "Element"}}]'
        script = "a = '" + request + "';" + "code_editor = $('#RequestConsole_CodeEditor .CodeMirror')[0].CodeMirror; code_editor.setValue(a);"
        self.driver.execute_script(script)

        editorHeader = self.driver.find_element_by_id("RequestConsole_CodeEditor__Header")
        editorHeaderColor = editorHeader.value_of_css_property("color")
        self.assertEqual('#000000', str(Color.from_string(editorHeaderColor).hex), 'RequestEditor header should be red, it is ' + str(Color.from_string(editorHeaderColor).hex))

    def test_requestEditor_redBorder_settingInvalidRequest(self):
        init(self.driver, self.HTML_FILE)

        request = '[{"SCHEMAERROR_getData": {"source": "Source","element": "Element"}}]'
        script = "a = '" + request + "';" + "code_editor = $('#RequestConsole_CodeEditor .CodeMirror')[0].CodeMirror; code_editor.setValue(a);"
        self.driver.execute_script(script)

        editorHeader = self.driver.find_element_by_id("RequestConsole_CodeEditor__Header")
        editorHeaderColor = editorHeader.value_of_css_property("color")
        self.assertEqual('#ff0000', str(Color.from_string(editorHeaderColor).hex), 'RequestEditor\'s header should be red, it is ' + str(Color.from_string(editorHeaderColor).hex))

    def test_responseEditor_normalBorder_withValidJSON(self):
        init(self.driver, self.HTML_FILE)

        request = '{"value":28}'
        script = "a = '" + request + "';" + "code_editor = $('#RequestConsole_ResponseDisplay .CodeMirror')[0].CodeMirror; code_editor.setValue(a);"
        self.driver.execute_script(script)

        script = "code_editor = $('#RequestConsole_ResponseDisplay .CodeMirror')[0].CodeMirror; return code_editor.getValue();"
        textInEditor = self.driver.execute_script(script)
        # the editor formats the code, so we have to remove line breaks and spaces
        textInEditor = re.sub(r"\s", "", textInEditor)
        self.assertEqual(request, textInEditor, "Response editor content can't be set")

        editorHeader = self.driver.find_element_by_id("RequestConsole_ResponseDisplay__Header")
        editorHeaderColor = editorHeader.value_of_css_property("color")
        self.assertEqual('#000000', str(Color.from_string(editorHeaderColor).hex), 'ResponseDisplay header should be red, it is ' + str(Color.from_string(editorHeaderColor).hex))

    def test_responseEditor_redBorder_withInvalidJSON(self):
        init(self.driver, self.HTML_FILE)

        request = '{"value"28}'
        script = "a = '" + request + "';" + "code_editor = $('#RequestConsole_ResponseDisplay .CodeMirror')[0].CodeMirror; code_editor.setValue(a);"
        self.driver.execute_script(script)

        editorHeader = self.driver.find_element_by_id("RequestConsole_ResponseDisplay__Header")
        editorHeaderColor = editorHeader.value_of_css_property("color")
        self.assertEqual('#ff0000', str(Color.from_string(editorHeaderColor).hex), 'ResponseDisplay header should be red, it is ' + str(Color.from_string(editorHeaderColor).hex))

    def test_responseEditor_normalBorder_withRealResponse(self):
        init(self.driver, self.HTML_FILE)

        sendRequest(self.driver);

        editorHeader = self.driver.find_element_by_id("RequestConsole_ResponseDisplay__Header")
        editorHeaderColor = editorHeader.value_of_css_property("color")
        self.assertEqual('#000000', str(Color.from_string(editorHeaderColor).hex), 'ResponseDisplay header should be red, it is ' + str(Color.from_string(editorHeaderColor).hex))

    def test_responseEditor_emptyListAfterEmptyRequest(self):
        init(self.driver, self.HTML_FILE)

        newSetup(self.driver);
        sendRequest(self.driver);

        script = "code_editor = $('#RequestConsole_ResponseDisplay .CodeMirror')[0].CodeMirror; return code_editor.getValue();"
        textInEditor = self.driver.execute_script(script)
        self.assertEqual("[]", textInEditor, "ResponseDisplay content is not [] as it should be")

    def test_sendRequest_checkResponse(self):
        init(self.driver, self.HTML_FILE)

        request = '[{"getData": {"source": "ExecCtrl", "element": "EntityGroups"}}]'
        script = "a = '" + request + "';" + "code_editor = $('#RequestConsole_CodeEditor .CodeMirror')[0].CodeMirror; code_editor.setValue(a);"
        self.driver.execute_script(script)

        sendRequest(self.driver);

        script = "code_editor = $('#RequestConsole_ResponseDisplay .CodeMirror')[0].CodeMirror; return code_editor.getValue();"
        textInEditor = self.driver.execute_script(script)

        expectedResponse = '[\n\
    {\n\
        "list": [\n\
            {\n\
                "node": {\n\
                    "val": "ExecCtrl EntityGroups 0",\n\
                    "tp": 4\n\
                }\n\
            },\n\
            {\n\
                "node": {\n\
                    "val": "ExecCtrl EntityGroups 1",\n\
                    "tp": 4\n\
                }\n\
            },\n\
            {\n\
                "node": {\n\
                    "val": "ExecCtrl EntityGroups 2",\n\
                    "tp": 4\n\
                }\n\
            }\n\
        ]\n\
    }\n\
]'
        self.assertEqual(expectedResponse, textInEditor, "sendData is not returning the expexted result")

if __name__ == "__main__":
    unittest.main(catchbreak=True, verbosity=2)