import os
import sys
import json
import hashlib
import pandas as pd
import random
from datetime import datetime, timedelta

from enrichsdk.datasets.discover import Dataset, DatabaseTable, \
           DatasetRegistry

def obfuscate(s):
    """
    Replace a string with  a hash
    """
    if ((s is None) or (pd.isnull(s))):
        return None
    if not isinstance(s, str):
        s = str(s)
    return hashlib.sha256(s.encode('utf-8')).hexdigest()[:16]

class AnonymizedDataset(Dataset):
    """
    Anonymize data before returning a sample
    """
    def sample(self, *args, **kwargs):
        safe = kwargs.get('safe', True)
        df = super().sample(*args, **kwargs)
        if not safe:
            return df

        # Anonymize additional columns...
        checkcols = ['alpha', 'beta']
        for c in df.columns:
            if len([check for check in checkcols if check in c]) > 0:
                df[c] = df[c]*random.randint(1,5)

        return df

datasets = []

############################################
# SQL-based datasets. These are typically generated by query execution
# engine, periodically based on pattern
############################################
for name,desc,sql in [
        ("DatasetName", "DatasetDescription", "SQLName")
]:
    d = AnonymizedDataset({
        "name": name,
        "alt_names": [sql],
        'description': desc,
        "paths": [
            {
                "nature": "s3",
                "name": "default",
                "path": "%(s3root)s/backup/%(node)s/rawdata/queries/" + sql
            },
        ],
        "match": {
            "generate": "generate_datetime_daily",
            "compare": "compare_datetime_pattern_match_range",
            "pattern": "%Y-%m-%d"
        },
        "subsets": [
            {
                "name": "Data",
                "pattern": ".*data.csv$"
            }
        ]
    })
    datasets.append(d)

############################################
# SQL-based datasets. These are typically generated by query execution
# engine, continuously replaced by the latest version..
############################################
for name,desc,sql in [
        ("ProviderCode","Provider Code", "provider_code"),
]:
    d = Dataset({
        "name": name,
        "alt_names": [sql],
        "description": desc,
        "paths": [
            {
                "nature": "s3",
                "name": "default",
                "path": "%(s3root)s/backup/%(node)s/rawdata/queries/" + sql
            },
        ],
        "match": {
            "generate": lambda start, end: [{ 'timestamp': 'complete', 'name': 'complete' }],
            "pattern": "*"
        },
        "subsets": [
            {
                "name": "Data",
                "pattern": ".*data.csv$"
            }
        ]
    })
    datasets.append(d)


############################################
# Feature Datasets. These are typically generated by pipelines. They
# will often have a version and timestamp as well..
############################################    
datasets.append(Dataset({
    "name": "DatasetName",
    "alt_names": ["cryptic_name"],
    "description": "Detailed description of the dataset",
    "paths": [
        {
            "nature": "s3",
            "name": "default",
            "path": "%(s3root)s/backup/%(node)s/data/customer/project/shared/datasetname/version/parameter"
        },
    ],
    "match": {
        "generate": "generate_datetime_daily",
        "compare": "compare_datetime_pattern_match_range",
        "pattern": "%Y-%m-%d"
    },
    "subsets": [
        {
            "name": "Sub-Dataset",
            "pattern": ".*sub-dataset.csv$"
        },
    ]
}))

def get_datasets(names=None):

    if names is not None and isinstance(names, list):
        return [ d for d in datasets if d.matches(names)]
    else:
        return datasets

def get_dataset(name):
    """
    Get the dataset object by name
    """
    for d in datasets:
        if d.matches(name):
            return d

    raise Exception("Unknown dataset: {}".format(name))

def get_registry(transform=None, state=None):

    registry = DatasetRegistry(transform=transform, state=state)
    registry.set_params({
        'enrich_data_dir': '/home/scribble/enrich/data',
        's3root': 'S3ROOT',
        'node': 'SERVERNAME',
        'remote_data_root': '/home/scribble/enrich'
    })

    registry.add_datasets(datasets)
    return registry
