from django.core.management.base import BaseCommand, CommandError
from products.models import *

class Command(BaseCommand):
    help = 'Import serial code from text file to a batch'

    def add_arguments(self, parser):
        parser.add_argument('--batch', '-b', required=True, type=int)
        parser.add_argument('--file', '-f', required=True)
        parser.add_argument('--job', '-j', type=int)

    def file_batch_iter(self, path, batchsize):
        this_batch = []
        for x in open(path, 'r'):
            x = x.strip()
            if x.startswith('#'):
                continue
            this_batch.append(x)
            if len(this_batch) >= batchsize:
                yield this_batch
                this_batch = []
        yield this_batch

    def handle(self, *args, **options):
        if options.get('job'):
            job = Job.objects.get(pk=options['job'])
        else:
            job = Job.objects.create(name='import-code.%d' % options.get('batch'))
        try:
            job.update('running', 0.0)
            fn = options['file']
            batchsize = 10000
            total = sum([len(x) for x in self.file_batch_iter(fn, batchsize)])
            done = 0
            b = CodeBatch.objects.get(pk=options['batch'])
            t = b.tenant
            for lines in self.file_batch_iter(fn, batchsize):
                objs = []
                if t:
                    seq_num = t.alloc_seq_nums(batchsize)
                else:
                    seq_num = None
                for code in lines:
                    obj = SerialCode(code=code, batch=b, tenant=t, seq_num=seq_num, is_active=b.is_active)
                    if seq_num:
                        seq_num += 1
                    objs.append(obj)
                done += len(objs)
                perc = done * 100.0 / total
                SerialCode.objects.bulk_create(objs, ignore_conflicts=True)
                print("[%d / %d]" % (done, total))
                job.update('running', perc)
            job.update('done', 100.0)
        except Exception as e:
            print(e)
            job.update('error', message=str(e))
        finally:
            print("deleting", fn)
            os.unlink(fn)
