#!/usr/bin/env python
# -*- coding: utf-8 -*-
#///////////////////////////////////////////////////////////////////////////////
#// Copyright (c) 2000-2019 Ericsson 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)