import sys
import json
import codecs
import re
import copy
import getopt

#for now contains dummy rules
class ValidationRule:

    def __init__(self, type, param = None):
        if type == "USER_REGEX":
            type = ValidationType.USER_REGEX
        if type == "NOT_NULL":
            type = ValidationType.NOT_NULL
        if type == "IS_URL":
            type = ValidationType.IS_URL
        if type == "MIN_ROWS":
            type = ValidationType.MIN_ROWS
        if type == "MAX_ROWS":
            type = ValidationType.MAX_ROWS
        if type == "RULE1":
            type = ValidationType.RULE1
        if type == "RULE2":
            type = ValidationType.RULE2
        if type == "RULE3":
            type = ValidationType.RULE3
        self.__method = type
        self.__param = param

    def execute_rule(self, field_extraction):
        #print "in execute_rule"
        return self.__method(field_extraction, self.__param)

    #apply user defined regular expreassion on extract
    def user_regex(self, field_extraction, regex):
        #print "in user_regex"
        extract = field_extraction['extract']
        regex = re.compile(regex)
        # apply pattern
        if regex.match(extract):
            # print "matched:", extract
            return True
        else:
            return False

    #check if extract is null or empty string
    def not_null(self, field_extraction, param = None):
        #print "in not_null"
        extract = field_extraction['extract']
        if extract is None or not extract:
            return False
        else:
            return True

    def is_url(self, field_extraction, param = None):
        #print "in is_url"
        extract = field_extraction['extract']
        regex = re.compile(
            #r'^(?:file):///'  # http:// or https://
            r'^(?:http|ftp)s?://'  # http:// or https://
            #r'^((?:http|ftp)s?://)|((?:file):///)' # http:// or https://
            r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|'  # domain...
            r'localhost|'  # localhost...
            r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'  # ...or ip
            r'(?::\d+)?'  # optional port
            r'(?:/?|[/?]\S+)$', re.IGNORECASE)

        #^(?:http|ftp)s?:\/\/(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|localhost|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(?::\d+)?(?:\/?|[\/?]\S+)$

        if regex.match(extract):
            # print "matched:", extract
            return True
        else:
            return False

    #returns true if the list contains at least min_rows
    def min_rows(self, list_extraction, min_rows):
        #print "in min_rows"
        #this is a list of rows
        #print "list:", list_extraction
        rows = list_extraction['sequence']
        if len(rows) < int(min_rows):
            return False
        else:
            return True

    #returns true if the list contains at most max_rows
    def max_rows(self, list_extraction, max_rows):
        #print "in max_rows"
        #this is a list of rows
        rows = list_extraction['sequence']
        print("rows:", len(rows))
        if len(rows) > int(max_rows):
            return False
        else:
            return True

    def rule1(self, extract, param = None):
        #print "in valid1"
        return True

    def rule2(self, extract, param = None):
        #print "in valid2"
        return True

    def rule3(self, extract, param = None):
        #print "in valid3"
        return False

    def __str__(self):
        output = str('rule:' + self.__method)
        return output


class ValidationType:
    USER_REGEX = ValidationRule.user_regex
    NOT_NULL = ValidationRule.not_null
    IS_URL = ValidationRule.is_url
    MIN_ROWS = ValidationRule.min_rows
    MAX_ROWS = ValidationRule.max_rows
    RULE1 = ValidationRule.rule1
    RULE2 = ValidationRule.rule2
    RULE3 = ValidationRule.rule3

#look at end of file for sample of extraction with validation metadata
#applies validation rules to extracted data and returns extraction json with validation metadata
class Validation:
    def __init__(self, validation_json):
        # validation_json = {"gh56fj78": [see below ...]}]
        # __validation: key = fieldid, value = json array with validation rules
        # [ { "type": "USER_REGEX",
        #     "param": "the regex" },
        #   { "type": "NOT_NULL" },
        #     etc.}
        self.__validation = validation_json

    def get_validations(self):
        return self.__validation