# -*- encoding: UTF8 -*-
# Test harness for ValidateContentFormat.py

from __future__ import print_function

import sys
import unittest
import os

import P4
from p4testutils import TestCase, P4Server, localDirectory, create_file, append_to_file

parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, parent_dir)
from ValidateContentFormat import ValidateContentFormat, yaml_validator, xml_validator

os.environ["LOGS"] = "."
LOGGER_NAME = "TestValidateContentFormat"
LOG_FILE = "log-ValidateContentFormat.log"

python3 = sys.version_info[0] >= 3

class TestValidateContentFormat(TestCase):
    def __init__(self, methodName='runTest'):
        super(TestValidateContentFormat, self).__init__(LOGGER_NAME, LOG_FILE, methodName=methodName)

    def setUp(self):
        pass

    def tearDown(self):
        pass

    def create_test_file(self, contents):
        fname = "~temp_file"
        with open(fname, "w") as f:
            f.write(contents)
        return fname

    def testValidateYaml(self):
        """Some basic yaml tests"""

        tfile = self.create_test_file("""
api: "api/v6"
user: swarmtest
ticket: A123453
""")
        result = yaml_validator(tfile)
        self.assertEqual("", result)

        tfile = self.create_test_file("""
review_description:
  - "Please review me!"
  - "Don't forget to check YYYY"
projects:
  - name:           ProjectA
    post_submit_create_review:  y
    require_job:    y
    update_review:  n
    depot_paths:
    - //depot/inside/...
    - "-//depot/inside/*_file1"
    default_reviewers:
    - user1
    - user2
""")
        result = yaml_validator(tfile)
        self.assertEqual("", result)

        tfile = self.create_test_file("""
review_description:
  - "Please review me!
  - "Don't forget to check YYYY"
""")
        result = yaml_validator(tfile)
        self.assertNotEqual("", result)

    def testValidateXML(self):
        """Some basic XML tests"""

        tfile = self.create_test_file("""<?xml version="1.0" ?>
<DTGGateway
    version="1"
    updated="2018/01/19 17:33:54 UTC">
    <DTGSettings
        id="mapName"
        force="1">
        <LastUpdateSCM>
            <Date
                year="2001"
                month="1"
                day="1"
                hour="0"
                minute="0"
                second="0" />
        </LastUpdateSCM>
    </DTGSettings>
</DTGGateway>
""")
        result = xml_validator(tfile)
        self.assertEqual("", result)

        tfile = self.create_test_file("""<?xml version="1.0" ?>
<DTGGateway
    version="1"
    updated="2018/01/19 17:33:54 UTC">
    <DTGSettings
        id="mapName"
        force="1">
        <LastUpdateSCM>
            <Date
                year="2001"
                month="1"
                day="1"
                hour="0"
                minute="0"
                second="0" />
        </LastUpdateSCM>
    </DTGSettings23234234234234234234234234234>
</DTGGateway>
""")
        result = xml_validator(tfile)
        self.assertNotEqual("", result)
        # self.assertEqual("", result)

    def testValidateContentFormatYAML(self):
        """trigger validates YAML"""
        self.server = P4Server()
        trig_path = os.path.join(parent_dir, "ValidateContentFormat.py")
        p4 = self.server.p4
        p4.logger = self.logger
        # This works if no spaces in server root pathname!
        port = p4.port.replace('"', '')
        self.logger.debug("port: |%s|" % port)
        triggers = p4.fetch_triggers()
        triggers['Triggers'] = ['validate-yaml change-content //....yaml " python ' + trig_path +
                                " -p %quote%" + port + "%quote% -u " + p4.user +
                               '  --yaml %change% "']
        self.logger.debug(triggers)
        p4.save_triggers(triggers)
        # Reconnect to pick up changes
        p4.disconnect()
        p4.connect()

        inside = localDirectory(self.server.client_root, "inside")
        inside_file1 = os.path.join(inside, "inside_file1.yaml")
        create_file(inside_file1, """
api: "api/v6"
user: swarmtest
ticket: A123453
""")

        p4.run('add', inside_file1)
        result = p4.run('submit', '-d', 'inside_file1 added')
        self.assertEqual("1", result[-1]['submittedChange'])

        # Bad yaml format is found
        p4.run('edit', inside_file1)
        create_file(inside_file1, """
review_description:
  - "Please review me!
  - "Don't forget to check YYYY"
""")
        try:
            result = p4.run('submit', '-d', 'inside_file1 edited')
            self.assertTrue(False, "Expected exception not found")
        except P4.P4Exception as e:
            self.assertRegex(str(e), r"Invalid format for")

        # Bad file without appropriate extension is OK because skipped
        inside_file2 = os.path.join(inside, "inside_file2")
        create_file(inside_file2, """
review_description:
  - "Please review me!
  - "Don't forget to check YYYY"
""")
        p4.run('add', inside_file2)
        result = p4.run('submit', '-d', 'inside_file2 added')
        self.assertEqual("3", result[-1]['submittedChange'])


    def testValidateContentFormatXML(self):
        """trigger validates XML"""
        self.server = P4Server()
        trig_path = os.path.join(parent_dir, "ValidateContentFormat.py")
        p4 = self.server.p4
        p4.logger = self.logger
        # This works if no spaces in server root pathname!
        port = p4.port.replace('"', '')
        self.logger.debug("port: |%s|" % port)
        triggers = p4.fetch_triggers()
        triggers['Triggers'] = ['validate-xml change-content //....xml " python ' + trig_path +
                                " -p %quote%" + port + "%quote% -u " + p4.user +
                               '  --xml %change% "']
        self.logger.debug(triggers)
        p4.save_triggers(triggers)
        # Reconnect to pick up changes
        p4.disconnect()
        p4.connect()

        inside = localDirectory(self.server.client_root, "inside")
        inside_file1 = os.path.join(inside, "inside_file1.xml")
        create_file(inside_file1, """<?xml version="1.0" ?>
<DTGGateway
    version="1"
    updated="2018/01/19 17:33:54 UTC">
    <DTGSettings
        id="mapName"
        force="1">
        <LastUpdateSCM>
            <Date
                year="2001"
                second="0" />
        </LastUpdateSCM>
    </DTGSettings>
</DTGGateway>
""")

        p4.run('add', inside_file1)
        result = p4.run('submit', '-d', 'inside_file1 added')
        self.assertEqual("1", result[-1]['submittedChange'])

        # Bad yaml format is found
        p4.run('edit', inside_file1)
        create_file(inside_file1, """<?xml version="1.0" ?>
<DTGGateway
    version="1"
    updated="2018/01/19 17:33:54 UTC">
    <DTGSettings
        id="mapName"
        force="1">
        <LastUpdateSCM>
            <Date
                year="2001"
                second="0" />
        </LastUpdateSCM>
    </DTGSettings23452345234523452345234523452354>
</DTGGateway>
""")
        try:
            result = p4.run('submit', '-d', 'inside_file1 edited')
            self.assertTrue(False, "Expected exception not found")
        except P4.P4Exception as e:
            self.assertRegex(str(e), r"Invalid format for")

        # Bad file without appropriate extension is OK because skipped
        inside_file2 = os.path.join(inside, "inside_file2")
        create_file(inside_file2, """<?xml version="1.0" ?>
<DTGGateway
    version="1"
    updated="2018/01/19 17:33:54 UTC">
    <DTGSettings
        id="mapName"
        force="1">
        <LastUpdateSCM>
            <Date
                year="2001"
                second="0" />
        </LastUpdateSCM>
    </DTGSettings23452345234523452345234523452354>
</DTGGateway>
""")
        p4.run('add', inside_file2)
        result = p4.run('submit', '-d', 'inside_file2 added')
        self.assertEqual("3", result[-1]['submittedChange'])

if __name__ == '__main__':
    unittest.main()
