import json

from django.db import models
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _

from django_enumfield import enum

from .excerpt import Excerpt


class ExtractionOrderState(enum.Enum):
    UNDEFINED = 0
    INITIALIZED = 1
    QUEUED = 2
    PROCESSING = 3
    FINISHED = 4
    CANCELED = 5
    FAILED = 6


CONVERSION_PROGRESS_TO_EXTRACTION_ORDER_STATE_MAPPING = {
    'new': ExtractionOrderState.INITIALIZED,
    'received': ExtractionOrderState.QUEUED,
    'started': ExtractionOrderState.PROCESSING,
    'successful': ExtractionOrderState.FINISHED,
    'error': ExtractionOrderState.FAILED,
}


def get_order_status_from_conversion_progress(progress):
    return CONVERSION_PROGRESS_TO_EXTRACTION_ORDER_STATE_MAPPING.get(progress, ExtractionOrderState.UNDEFINED)


class ExtractionOrder(models.Model):
    DOWNLOAD_STATUS_NOT_DOWNLOADED = 0
    DOWNLOAD_STATUS_DOWNLOADING = 1
    DOWNLOAD_STATUS_AVAILABLE = 2

    DOWNLOAD_STATUSES = (
        (DOWNLOAD_STATUS_NOT_DOWNLOADED, 'unknown'),
        (DOWNLOAD_STATUS_DOWNLOADING, 'downloading'),
        (DOWNLOAD_STATUS_AVAILABLE, 'received'),
    )

    state = enum.EnumField(ExtractionOrderState, default=ExtractionOrderState.INITIALIZED, verbose_name=_('state'))
    _extraction_configuration = models.TextField(
        blank=True, null=True, default='', verbose_name=_('extraction options')
    )
    process_id = models.TextField(blank=True, null=True, verbose_name=_('process link'))
    orderer = models.ForeignKey(User, related_name='extraction_orders', verbose_name=_('orderer'))
    excerpt = models.ForeignKey(Excerpt, related_name='extraction_orders', verbose_name=_('excerpt'), null=True)
    country_id = models.IntegerField(verbose_name=_('country ID'), null=True, blank=True)
    progress_url = models.URLField(verbose_name=_('progress URL'), null=True, blank=True)
    download_status = models.IntegerField(
        _('file status'),
        choices=DOWNLOAD_STATUSES,
        default=DOWNLOAD_STATUS_NOT_DOWNLOADED
    )

    def __str__(self):
        return ', '.join(
            [
                '[{order_id}] orderer: {orderer_name}',
                'excerpt: {excerpt}',
                'state: {state}',
                'output files: {number_of_output_files}',
            ]
        ).format(
            order_id=self.id,
            orderer_name=self.orderer.get_username(),
            excerpt=str(self.excerpt_name),
            state=self.get_state_display(),
            number_of_output_files=str(self.output_files.count()),
        )

    @property
    def excerpt_name(self):
        """
        Returns:
              user-given excerpt name for user-defined excerpts,
              country name for countries,
              None if order has no excerpt (neither country nor user-defined)
        """
        if self.excerpt:
            return self.excerpt.name
        elif self.country_id:
            from osmaxx.excerptexport.services.shortcuts import get_authenticated_api_client
            return get_authenticated_api_client().get_country_name(self.country_id)

    @property
    def are_downloads_ready(self):
        return self.state == ExtractionOrderState.FINISHED

    @property
    def extraction_configuration(self):
        if self._extraction_configuration and not self._extraction_configuration == '':
            return json.loads(self._extraction_configuration)
        else:
            return None

    @extraction_configuration.setter
    def extraction_configuration(self, value):
        """
        :return example:
            {
                'gis_formats': ['txt', 'file_gdb'],
                'gis_options': {
                    'coordinate_reference_system': 'wgs72',
                    'detail_level': 'verbatim'
                },
                'routing': { ... }
            }
        """
        if not value:
            value = {}
        self._extraction_configuration = json.dumps(value)

    @property
    def extraction_formats(self):
        return json.loads(self.extraction_configuration).get('gis_formats', None)

    def set_status_from_conversion_progress(self, job_overall_progress):
        if self.state not in [ExtractionOrderState.FINISHED, ExtractionOrderState.FAILED]:
            self.state = get_order_status_from_conversion_progress(job_overall_progress)

@@ -2173,163 +2173,8 @@
 me%7D'
-,%0A                'excerpt: %7Bexcerpt%7D',%0A                'state: %7Bstate%7D',%0A                'output files: %7Bnumber_of_output_files%7D',%0A            %5D%0A        )
 .for
@@ -2178,16 +2178,24 @@
 format(%0A
+        
         
@@ -2216,16 +2216,24 @@
 elf.id,%0A
+        
         
@@ -2294,16 +2294,52 @@
     
+    
-excerpt=
+),%0A                'excerpt: %7B%7D'.format(
 str(
@@ -2356,16 +2356,17 @@
 pt_name)
+)
 ,%0A      
@@ -2375,14 +2375,31 @@
     
-state=
+    'state: %7B%7D'.format(
 self
@@ -2418,16 +2418,17 @@
 isplay()
+)
 ,%0A      
@@ -2437,31 +2437,38 @@
     
-number_of_
+    '
 output
-_
+ 
 files
-=
+: %7B%7D'.format(
 str(
@@ -2493,17 +2493,32 @@
 count())
-,
+),%0A            %5D
 %0A       

format substrings rather than joined result