from factory import Faker, Iterator, PostGenerationMethodCall, SubFactory
from factory.django import DjangoModelFactory
from django.utils.timezone import get_default_timezone

from apps.data.factories import EntryFactory, RepositoryFactory
from . import models

PIXELER_PASSWORD = 'SurferRosa1988'


class SpeciesFactory(DjangoModelFactory):

    name = Faker('word')
    reference = SubFactory(EntryFactory)
    repository = SubFactory(RepositoryFactory)
    description = Faker('text', max_nb_chars=300)

    class Meta:
        model = 'core.Species'
        django_get_or_create = ('name', )


class StrainFactory(DjangoModelFactory):

    name = Faker('word')
    description = Faker('text', max_nb_chars=300)
    species = SubFactory(SpeciesFactory)
    reference = SubFactory(EntryFactory)

    class Meta:
        model = 'core.Strain'
        django_get_or_create = ('name', )


class OmicsUnitTypeFactory(DjangoModelFactory):

    name = Faker('word')
    description = Faker('text', max_nb_chars=300)

    class Meta:
        model = 'core.OmicsUnitType'
        django_get_or_create = ('name', )


class OmicsUnitFactory(DjangoModelFactory):

    reference = SubFactory(EntryFactory)
    strain = SubFactory(StrainFactory)
    type = SubFactory(OmicsUnitTypeFactory)
    status = Iterator(s[0] for s in models.OmicsUnit.STATUS_CHOICES)

    class Meta:
        model = 'core.OmicsUnit'
        django_get_or_create = ('reference', 'strain')


class PixelerFactory(DjangoModelFactory):

    username = Faker('user_name')
    password = PostGenerationMethodCall(
        'set_password', PIXELER_PASSWORD
    )
    email = Faker('email')
    first_name = Faker('first_name')
    last_name = Faker('last_name')
    is_active = Faker('pybool')
    is_staff = Faker('pybool')
    is_superuser = Faker('pybool')
    date_joined = Faker('date_time_this_decade', tzinfo=get_default_timezone())
    last_login = Faker('date_time_this_decade', tzinfo=get_default_timezone())

    class Meta:
        model = 'core.Pixeler'
        django_get_or_create = ('username',)


class OmicsAreaFactory(DjangoModelFactory):
    description = Faker('text', max_nb_chars=300)
    level = Faker('pyint')
    lft = Faker('pyint')
    name = Faker('word')
    rght = Faker('pyint')
    tree_id = Faker('pyint')

    class Meta:
        model = 'core.OmicsArea'
        django_get_or_create = ('name',)


class ExperimentFactory(DjangoModelFactory):
    omics_area = SubFactory(OmicsAreaFactory)
    created_at = Faker('datetime')
    description = Faker('text', max_nb_chars=300)
    released_at = Faker('datetime')
    saved_at = Faker('datetime')

    class Meta:
        model = 'core.Experiment'
        django_get_or_create = ('omics_area', 'created_at')


class AnalysisFactory(DjangoModelFactory):
    pixeler = SubFactory(PixelerFactory)
    created_at = Faker('date')
    description = Faker('text', max_nb_chars=300)
    notebook = Faker('file_path', depth=1, category=None, extension=None)
    saved_at = Faker('date')
    secondary_data = Faker('file_path', depth=1, category=None, extension=None)

    class Meta:
        model = 'core.Analysis'
        django_get_or_create = ('secondary_data', 'pixeler',)


class PixelFactory(DjangoModelFactory):

    value = Faker('pyfloat')
    quality_score = Faker('pyfloat', left_digits=0)
    omics_unit = SubFactory(OmicsUnitFactory)
    analysis = SubFactory(AnalysisFactory)

    class Meta:
        model = 'core.Pixel'
        django_get_or_create = ('value', 'omics_unit', 'analysis')

@@ -2103,24 +2103,50 @@
 delFactory):
+%0A%0A    name = Faker('word')
 %0A    descrip
@@ -2187,140 +2187,8 @@
 300)
-%0A    level = Faker('pyint')%0A    lft = Faker('pyint')%0A    name = Faker('word')%0A    rght = Faker('pyint')%0A    tree_id = Faker('pyint')
 %0A%0A  
@@ -2318,24 +2318,25 @@
 elFactory):%0A
+%0A
     omics_ar
@@ -2373,43 +2373,8 @@
 ry)%0A
-    created_at = Faker('datetime')%0A
     
@@ -2415,24 +2415,59 @@
 _chars=300)%0A
+    created_at = Faker('datetime')%0A
     released
@@ -2683,79 +2683,8 @@
 y):%0A
-    pixeler = SubFactory(PixelerFactory)%0A    created_at = Faker('date')
 %0A   
@@ -2726,24 +2726,65 @@
 _chars=300)%0A
+    pixeler = SubFactory(PixelerFactory)%0A
     notebook
@@ -2849,37 +2849,8 @@
 ne)%0A
-    saved_at = Faker('date')%0A
     
@@ -2924,16 +2924,76 @@
 on=None)
+%0A    created_at = Faker('date')%0A    saved_at = Faker('date')
 %0A%0A    cl

Improve core factories coding style