import time
import shutil
import tempfile
import subprocess
import requests
import datetime
import os
from django.utils import timezone
from django.core.management.base import BaseCommand, CommandError
from products.models import *
from products.aliyun import oss_sign_url
from django.core import serializers

class Command(BaseCommand):
    help = 'Export scan data to a zip file'

    def add_arguments(self, parser):
        parser.add_argument('--output', '-o', required=True, help="output file")
        parser.add_argument('--job', '-j', type=int, help="The job object to report progress")
        parser.add_argument('--hours', '-H', type=int, help="how many hours")

    def download(self, url, p):
        r = requests.get(url, allow_redirects=True)
        d = os.path.dirname(p)
        os.makedirs(d, exist_ok=True)
        with open(p, 'wb') as f:
            f.write(r.content)

    def do_export(self, job, workdir, hours, part_prog):
        subprocess.check_output(["mkdir", "-p", "images"], cwd=workdir)
        start = timezone.now() - datetime.timedelta(hours=hours)
        records = ScanData.objects.filter(datetime__gt=start)
        total = records.count() + 1
        done = 0
        print("total:", total)
        for r in records:
            url = oss_sign_url(r.image)
            p = os.path.join(workdir, 'images', r.image)
            done += 1
            self.download(url, p)
            perc = done * part_prog / total
            print("[%d/%d %.1f%%]" % (done, total, perc))
            job.update('running', perc)
        j = serializers.serialize('json', records)
        print(j)
        with open(os.path.join(workdir, 'data.json'), 'w') as f:
            f.write(j)

    def handle(self, *args, **options):
        if options.get('job'):
            job = Job.objects.get(pk=options['job'])
        else:
            job = Job.objects.create(name='export-scan-data.%d' % time.time())
        td = None
        try:
            job.update('running', 0.0)
            td = tempfile.mkdtemp()
            self.do_export(job, td, options['hours'], 80)
            cmd = ['zip', '-r', os.path.abspath(options['output']), '.']
            print(cmd)
            subprocess.check_call(cmd, cwd=td)
            job.update('done', 100.0)
        except Exception as e:
            job.update('error', message=str(e))
        finally:
            if td:
                shutil.rmtree(td)
