import random
import tzlocal
import datetime

from slugify import slugify
from faker import Factory

from settings import LOG_FILE


class Sitemap:

    """
    Generates random url for our log using randomly selected method.
    """

    _methods = ('company', 'person', 'job', )

    def __init__(self):
        self.fake = Factory.create()

    def __new__(cls):
        """
        Create `Sitemap` singleton

        :return: `Sitemap` instance
        """
        if not hasattr(cls, 'instance'):
            cls.instance = super(Sitemap, cls).__new__(cls)

        return cls.instance

    @property
    def company(self):
        """
        :return: randomly generated url with company name.
        """
        return '/company/' + slugify(self.fake.company())

    @property
    def person(self):
        """
        :return: randomly generated url with person name.
        """
        return '/person/' + slugify(self.fake.name())

    @property
    def job(self):
        """
        :return: randomly generated url with job name.
        """
        return '/job/' + slugify(self.fake.job())

    @classmethod
    def url(cls):
        """
        Pick random class method and generate docstring.

        :return: random string generated by one of the methods
        """
        return getattr(Sitemap(), random.choice(cls._methods))


def random_ip():
    """
    Generate random IP.

    :return:
    """
    return '.' . join(str(random.randint(1, 255)) for _ in range(4))


def generate_logs(lines=1):
    """
    Using different amount of lines will give us option to simulate traffic spikes.

    :param lines:
    :return:
    """
    now = datetime.datetime.now(tzlocal.get_localzone())
    for _ in range(lines):
        yield ("{} - - [{}] \"{} {} HTTP/1.1\" {} {}".format(
            random_ip(),
            now.strftime('%d/%b/%Y:%H:%M:%S %z'),
            random.choice(HTTP_METHODS),
            Sitemap.url(),
            random.choice(HTTP_CODES),
            random.randrange(1, 9999)
        ))

HTTP_METHODS = ('GET', 'POST')
HTTP_CODES = (200, 400, 404, 500)


if __name__ == '__main__':
    with open(LOG_FILE, 'w') as file:
        while True:
            for log in generate_logs(lines=random.randint(1, 5)):
                file.write(log + '\n')
                file.flush()
