from django.db import transaction

from samples.models import Sample
from users.models import WinoseUser
from .generators import *
from clients.models import ClientOffice, Client, ClientCategory, ContactPerson
from panelists.models import Panelist
from referencegases.models import ReferenceGas
from history.models import HistoryEntry
from bags.models import Bag, BagMaterial
from projects.models import Project
from devices.models import Olfactometer, Calibration

panelist_count = 150
bag_count = 500
sample_odour = 100
sample_ref = 200
cylinder_count = 10
project_count = 30

transaction.set_autocommit(False)

# clear old stuff.
HistoryEntry.objects.all().delete()

WinoseUser.objects.all().delete()

admin = WinoseUser.objects.create_superuser('burns', 'burns@nuclear.org', 'onde', last_name='Burns',
                                            first_name='Montgomery')

qa_guy = WinoseUser.objects.create_user('qapersons', 'qa@seemsimportant.org', 'onde', last_name='qa',
                                        first_name='person')
qa_guy.user_group = 'L'
qa_guy.save()

olf_guy = WinoseUser.objects.create_user('meg', 'shut@up.meg', 'onde', last_name='Griffin', first_name='Megan')
olf_guy.user_group = ''
olf_guy.save()

lab_guy = WinoseUser.objects.create_user('stewie', 'what_the@deu.ce', 'onde', last_name='Griffin', first_name='Stewie')
lab_guy.user_group = 'A'
lab_guy.save()

random.seed()

# clear old stuff
ClientOffice.objects.all().delete()
Client.objects.all().delete()
ContactPerson.objects.all().delete()
ClientCategory.objects.all().delete()

cat_objs = list()
for cat in categories:
    c = ClientCategory()
    c.name = cat
    c.is_active = True
    c.save()
    cat_objs.append(c)

while len(companies) > 0:
    cl = Client()
    generate_address(cl)
    cl.name = random_company()
    cl.reference = random_reference()
    cl.category = random.choice(cat_objs)
    cl.is_active = random.random() < 0.8
    cl.save()  # must save here else foreign keys won't work
    # client has at least one office
    for y in range(random.randint(1, 3)):
        cl_of = ClientOffice()
        generate_address(cl_of)
        cl_of.mobile = random_phone()
        cl_of.phone = random_phone()
        cl_of.email = ('{0}_{1}@{2}'.format(cl.name, cl_of.city, random.choice(mail_provider))).lower().replace(' ', '')
        cl_of.email.lower()
        cl_of.department = random_department()
        cl_of.reference = random_reference()
        cl_of.is_active = cl.is_active
        cl_of.client = cl

        # create optional contact for this office
        if random.random() < 0.75:
            # chance to reuse someone
            if ContactPerson.objects.all().count() > 0 and random.random() < 0.33:
                cl_of_cp = \
                    ContactPerson.objects.all()[random.randint(0, ContactPerson.objects.all().count() - 1)]
            else:
                cl_of_cp = ContactPerson()
                generate_person(cl_of_cp)
                generate_contact_data(cl_of_cp)
                cl_of_cp.email = mail_for_person(cl_of_cp)
                cl_of_cp.title = random_title()
                cl_of_cp.is_active = True
                cl_of_cp.save()
            cl_of.contact = cl_of_cp

        cl_of.save()

print("done clients/offices")

Panelist.objects.all().delete()

# make us some panelists (some more...)
for x in range(panelist_count):
    p = Panelist()
    generate_address(p)
    generate_person(p)
    generate_contact_data(p)
    p.email = mail_for_person(p)
    p.date_of_birth = random_age()
    p.is_active = random.random() < 0.8
    p.save()

print("panelists done")

ReferenceGas.objects.all().delete()

for _ in range(cylinder_count):
    cyl = ReferenceGas()
    cyl.number = cyl.name = random_reference()

    cyl.concentration = 59.1 + random.random()

    # bring some of them into service
    if random.random() < 0.33:
        cyl.in_service_since = random_date_before_now()

    cyl.is_active = random.random() < 0.8

    if random.random() < 0.7:
        cyl.substance = 'B'
    else:
        cyl.substance = 'H'
    cyl.supplier = random.choice(['Linde', 'BASF', 'Westfalen'])
    cyl.expires_at = datetime.now() + timedelta(days=random.randint(600, 900))
    cyl.save()

Bag.objects.all().delete()

bag_mats = ['Nalophan', 'Tedlar', 'stainless steel', 'PET']
BagMaterial.objects.all().delete()
for bm in bag_mats:
    bm_obj = BagMaterial()
    bm_obj.name = bm
    bm_obj.is_active = True
    bm_obj.save()

for x in range(bag_count):
    b = Bag()
    b.name = 'Bag_{0}'.format(x)
    b.manufactured_at = random_date_before_now()
    b.material = random.choice(BagMaterial.objects.all())
    b.is_active = random.random() < 0.8
    b.save()

print('bags done')

all_clients = ClientOffice.objects.all()
cps = ContactPerson.objects.all()
Project.objects.all().delete()

for x in range(project_count):
    proj = Project()
    proj.name = random_reference()
    proj.reference = random_reference()
    proj.client = random.choice(all_clients)
    proj.is_active = random.random() < 0.8
    if random.random() < 0.75:
        proj.contact = random.choice(cps)
    if random.random() < 0.75:
        proj.project_manager = random.choice(cps)
    proj.save()

calib_set = Calibration()

with open('test_data/calibration_set_example.json') as file:
    from json import load as load_json
    from json import dumps

    as_dict = load_json(file)
    calib_set.json_data = dumps(as_dict['calibration_set'])
    calib_set.json_data = calib_set.json_data.replace("\"", "'")
    calib_set.valid_to = as_dict['valid_to']
    calib_set.created_for = as_dict['serial']
    calib_set.save()

Olfactometer.objects.all().delete()
dev = Olfactometer()
dev.name = 'TO8'
dev.inventory_number = 'TO8-391 ONSE'
dev.serial_no = 'EO.1'
dev.calibration = calib_set
dev.save()

dev_virt = Olfactometer()
dev_virt.name = 'VirtualDevice'
dev_virt.inventory_number = '42'
dev_virt.serial_no = 'FakeEvo'
dev_virt.calibration = calib_set
dev_virt.save()

all_projs = Project.objects.all()
all_bags = Bag.objects.all()
all_cyl = ReferenceGas.objects.all()

from datetime import datetime

# generate some odour samples...
for i in range(sample_odour):
    s = Sample()
    s.project = random.choice(all_projs)
    s.comments = s.name = 'smelly stuff {0}'.format(i)
    s.contained_in = random.choice(
        Bag.objects.filter(sample__isnull=True, is_active=True))
    s.sampled_at = datetime.now(tz=utc)
    if random.random() > 0.5:
        s.factor = 1 + 5.0 * random.random()
    s.save()

# keep on faking... set status for projects which has at least one sample to
# analysis, to ensure it shows up in the control software
all_projs_with_samples = Project.objects.filter(samples__isnull=False)

for p in all_projs_with_samples:
    p.save()

# and some reference samples
for i in range(sample_ref):
    s = Sample()
    s.cylinder = random.choice(all_cyl)
    s.sampled_at = datetime.now(tz=utc)
    s.comments = 'le wild reference gas appears'
    s.contained_in = random.choice(
        Bag.objects.filter(sample__isnull=True, is_active=True))
    s.name = 'refgas {0}'.format(i)
    # if random.random() > 0.5:
    # s.factor = 1 + 5.0 * random.random()
    if random.random() > 0.5:
        s.project = random.choice(all_projs)
    s.save()

print('samples done')

from report_template.models import ReportTemplate

ReportTemplate.objects.all().delete()
myTemplate = ReportTemplate()
myTemplate.name = 'testTemplate'
myTemplate.insufficient_volume_remark = 'the sample did not provide enough volume to finish a complete measurement.'
myTemplate.lower_threshold = 64.0
myTemplate.lower_threshold_remark = 'the odour concentration was below the lower limit of detection.'
myTemplate.late_analysis_text = 'the sample was not analyzed in time.'
myTemplate.client_bag_remark = 'the bag containing the sample was supplied by the client and is thus not covered by ' \
                               'the whatever accreditation'
myTemplate.not_standard_compliant_remark = 'measurement was not conducted under en13725'
myTemplate.header_text = 'Odournet GmbH\n\nFraunhoferstr. 13\n24118 Kiel'
myTemplate.footer_text = 'the wild footer text appears and looks awesome!'

myTemplate.save()

transaction.commit()
transaction.set_autocommit(True)
