import unittest
import datetime
import os
import pprint
import string
import re

from OTXv2 import OTXv2, InvalidAPIKey, BadRequest
from suricata import SuricataClient
import IndicatorTypes

ALIEN_API_APIKEY = os.getenv('X_OTX_API_KEY', "mysecretkey")
STRP_TIME_FORMAT = '%Y-%m-%dT%H:%M:%S.%f'
# Rule regex autogenerated by http://regex.inginf.units.it/
FILE_RULE_REGEX = "^alert[^;]+[^\)]+\)$"
# Overly complex rules? Credit http://stackoverflow.com/questions/53497/regular-expression-that-matches-valid-ipv6-addresses
IPV4_RULE_REGEX = "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?),"
IPV6_RULE_REGEX = "^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))"

# Class names should start with "Test"
class TestOTXv2(unittest.TestCase):
    """
    Base class configure API Key to use on a per test basis.
    """
    def setUp(self, **kwargs):
        provided_key = kwargs.get('api_key', '')
        if provided_key:
            self.api_key = provided_key
        else:
            self.api_key = ALIEN_API_APIKEY
        self.suricata_client = SuricataClient(self.api_key, "./")


# Generate some rules. Test that they're not empty, and that there is at least one rule in a valid format in there
class TestGenerateRules(TestOTXv2):

    def setUp(self, **kwargs):
        super(TestGenerateRules, self).setUp(**{'api_key': ALIEN_API_APIKEY})

    def testRuleGenerate(self):
        self.suricata_client.generate_rules(True, True)

        file_rules = []
        with open('otx_file_rules.rules', 'r') as f:
            file_rules = f.readlines()
        # Check > 0 lines
        self.assertTrue(file_rules)
        # Check each rule matches a very lax regex
        for rule in file_rules:
            print ("- Validating file rule [" + rule.strip() + "]")
            self.assertTrue(re.match(FILE_RULE_REGEX, rule.strip()))


        ip_rules = []
        with open('reputation.list', 'r') as f:
            ip_rules = f.readlines()
        # Check > 0 lines
        self.assertTrue(ip_rules)
        # Check each rule matches a very lax regex
        for rule in ip_rules:
            print ("- Validating IP rule [" + rule.strip() + "]")
            self.assertTrue(re.match(IPV4_RULE_REGEX, rule.strip()) or re.match(IPV6_RULE_REGEX, rule.strip()))



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