# coding=utf-8

from __future__ import unicode_literals
import re
import random


class Generator(object):

    __config = {}

    def __init__(self, **config):
        self.providers = []
        self.__config = dict(list(self.__config.items()) + list(config.items()))

    def add_provider(self, provider):

        if type(provider) is type:
            provider = provider(self)

        self.providers.insert(0, provider)

        for method_name in dir(provider):
            # skip 'private' method
            if method_name.startswith('_'):
                continue

            faker_function = getattr(provider, method_name)

            if hasattr(faker_function, '__call__') or isinstance(faker_function, (classmethod, staticmethod)):
                # add all faker method to generator
                self.set_formatter(method_name, faker_function)

    def provider(self, name):
        try:
            return list(filter(lambda p: p.__provider__ == name.lower(), self.get_providers()))[0]
        except IndexError:
            return None

    def get_providers(self):
        """
        returns added providers
        """
        return self.providers

    def seed(self, seed=None):
        """
        calls random.seed
        """
        random.seed(seed)

    def format(self, formatter, *args, **kwargs):
        """
        this is a secure way to make a fake
        from other Provider
        TODO: data export?
        """
        return self.get_formatter(formatter)(*args, **kwargs)

    def get_formatter(self, formatter):
        try:
            return getattr(self, formatter)
        except AttributeError:
            raise AttributeError('Unknown formatter "{0}"'.format(formatter))

    def set_formatter(self, name, method):
        """
        This method adds a provider method to generator.
        Override this method to add some decoration or logging stuff.
        """
        setattr(self, name, method)

    def parse(self, text):
        """
        Replaces tokens ('{{ tokenName }}') with the result from the token method call
        """
        return re.sub(r'\{\{(\s?)(\w+)(\s?)\}\}', self.__format_token, text)
        #return re.sub( r'\{\{\s?(\w+)\s?\}\}', lambda matches: ( self.format( matches.group(1) ) ) , text )

    def __format_token(self, matches):
        formatter = list(matches.groups())
        #args = []
        #if ':' in formatter[1]:
        #    formatter[1], args = formatter[1].split(":")
        #    args = args.split(",")
        formatter[1] = self.format(formatter[1])

        return "".join(formatter)
@@ -49,16 +49,17 @@
 iterals%0A
+%0A
 import r
@@ -212,16 +212,29 @@
  = dict(
+%0A            
 list(sel
@@ -698,16 +698,38 @@
 __') or 
+%5C%0A                    
 isinstan
@@ -1009,16 +1009,47 @@
 lower(),
+%0A                              
  self.ge
@@ -1155,34 +1155,25 @@
 %0A        %22%22%22
-%0A        r
+R
 eturns added
@@ -1182,25 +1182,17 @@
 roviders
-%0A        
+.
 %22%22%22%0A    
@@ -1264,18 +1264,9 @@
  %22%22%22
-%0A        c
+C
 alls
@@ -1277,25 +1277,16 @@
 dom.seed
-%0A        
 %22%22%22%0A    
@@ -1378,17 +1378,17 @@
         
-t
+T
 his is a
@@ -1417,22 +1417,16 @@
 fake
-%0A       
  from 
+an
 othe
@@ -1435,24 +1435,39 @@
 Provider
-%0A
+.%0A  
       
- 
+%22%22%22%0A        #
  TODO: d
@@ -1478,28 +1478,16 @@
 export?%0A
-        %22%22%22%0A
         
@@ -2043,16 +2043,21 @@
 tokens (
+like 
 '%7B%7B toke
@@ -2082,16 +2082,24 @@
 e result
+%0A       
  from th
@@ -2117,16 +2117,17 @@
 hod call
+.
 %0A       
@@ -2212,344 +2212,89 @@
 xt)%0A
-        #return re.sub( r'%5C%7B%5C%7B%5Cs?(%5Cw+)%5Cs?%5C%7D%5C%7D', lambda matches: ( self.format( matches.group(1) ) ) , text )%0A%0A    def __format_token(self, matches):%0A        formatter = list(matches.groups())%0A        #args = %5B%5D%0A        #if ':' in formatter%5B1%5D:%0A        #    formatter%5B1%5D, args = formatter%5B1%5D.split(%22:%22)%0A        #    args = args.split(%22,%22
+%0A    def __format_token(self, matches):%0A        formatter = list(matches.groups()
 )%0A  
@@ -2340,17 +2340,16 @@
 ter%5B1%5D)%0A
-%0A
         
@@ -2365,16 +2365,17 @@
 .join(formatter)
+%0A

Apply PEP8 to generator.py