from __future__ import unicode_literals

import os
import shutil
import logging
import tempfile
import subprocess
import xml.etree.ElementTree as ET

from django.db import migrations
from django.core.files.uploadedfile import UploadedFile

from django_irods.storage import IrodsStorage
from hs_core import hydroshare
from hs_core.hydroshare.utils import resource_modified, get_file_from_irods
from hs_geo_raster_resource.models import RasterResource
from hs_geo_raster_resource import raster_meta_extract


def migrate_tif_file(apps, schema_editor):
    log = logging.getLogger()

    copy_res_fail = []
    meta_update_fail = []
    meta_update_success = []

    # start migration for each raster resource that has raster files
    for res in RasterResource.objects.all():
        if res.files.all():
            # copy all the resource files to temp dir
            temp_dir = ''
            res_file_tmp_path = ''

            try:
                temp_dir = tempfile.mkdtemp()
                for res_file in res.files.all():
                    res_file_tmp_path = get_file_from_irods(res_file)
                    shutil.copy(res_file_tmp_path,
                                os.path.join(temp_dir, os.path.basename(res_file_tmp_path)))
                    shutil.rmtree(os.path.dirname(res_file_tmp_path))

                vrt_file_path = [os.path.join(temp_dir, f) for f in os.listdir(temp_dir) if '.vrt' == f[-4:]].pop()

            except Exception as e:
                if os.path.isdir(temp_dir):
                    shutil.rmtree(temp_dir)
                if os.path.isfile(res_file_tmp_path):
                    shutil.rmtree(os.path.dirname(res_file_tmp_path))
                log.exception(e.message)
                copy_res_fail.append('{}:{}'.format(res.short_id, res.metadata.title.value))
                continue

            # update the metadata for the original coverage information of all the raster resources
            try:
                meta_updated = False

                # extract meta
                ori_dir = os.getcwd()
                os.chdir(temp_dir)
                res_md_dict = raster_meta_extract.get_raster_meta_dict(vrt_file_path)
                os.chdir(ori_dir)
                shutil.rmtree(temp_dir)

                # update original coverage information for datum and coordinate string in django
                if res.metadata.originalCoverage:
                    res.metadata.originalCoverage.delete()
                    v = {'value': res_md_dict['spatial_coverage_info']['original_coverage_info']}
                    res.metadata.create_element('OriginalCoverage', **v)
                    meta_updated = True

                # update the bag if meta is updated
                if meta_updated:
                    bag_name = 'bags/{res_id}.zip'.format(res_id=res.short_id)
                    istorage = res.get_irods_storage()
                    if istorage.exists(bag_name):
                        # delete the resource bag as the old bag is not valid
                        istorage.delete(bag_name)
                    resource_modified(res, res.creator)
                    meta_update_success.append('{}:{}'.format(res.short_id, res.metadata.title.value))

            except Exception as e:
                if os.path.isdir(temp_dir):
                    shutil.rmtree(temp_dir)
                log.exception(e.message)
                meta_update_fail.append('{}:{}'.format(res.short_id, res.metadata.title.value))

    # Print migration results
    print 'Copy resource to temp folder failure: Number: {} List: {}'.format(len(copy_res_fail), copy_res_fail)
    print 'Meta update success: Number: {} List {}'.format(len(meta_update_success), meta_update_success)
    print 'Meta update fail: Number: {} List {}'.format(len(meta_update_fail), meta_update_fail)


def undo_migrate_tif_file(apps, schema_editor):
    pass


class Migration(migrations.Migration):

    dependencies = [
        ('hs_geo_raster_resource', 'custom_migration_for_raster_meta_update_20160512'),
    ]

    operations = [
        migrations.RunPython(code=migrate_tif_file, reverse_code=undo_migrate_tif_file),
    ]

@@ -771,40 +771,9 @@
 ():%0A
-        if res.files.all():%0A    
+%0A
     
@@ -818,20 +818,16 @@
 emp dir%0A
-    
         
@@ -840,36 +840,32 @@
 ir = ''%0A        
-    
 res_file_tmp_pat
@@ -872,36 +872,32 @@
 h = ''%0A%0A        
-    
 try:%0A           
@@ -893,28 +893,24 @@
             
-   
- 
 temp_dir = t
@@ -927,20 +927,16 @@
 dtemp()%0A
-    
         
@@ -984,28 +984,24 @@
             
- 
-   
 res_file_tmp
@@ -1050,28 +1050,24 @@
             
-   
- 
 shutil.copy(
@@ -1085,20 +1085,16 @@
 p_path,%0A
-    
         
@@ -1182,36 +1182,32 @@
                 
-    
 shutil.rmtree(os
@@ -1253,20 +1253,16 @@
         
-  
-  
 vrt_file
@@ -1354,36 +1354,32 @@
 .pop()%0A%0A        
-    
 except Exception
@@ -1377,36 +1377,32 @@
 Exception as e:%0A
-    
             if o
@@ -1433,36 +1433,32 @@
                 
-  
-  
 shutil.rmtree(te
@@ -1457,36 +1457,32 @@
 mtree(temp_dir)%0A
-    
             if o
@@ -1523,36 +1523,32 @@
                 
-    
 shutil.rmtree(os
@@ -1585,36 +1585,32 @@
 h))%0A            
- 
-   
 log.exception(e.
@@ -1610,36 +1610,32 @@
 tion(e.message)%0A
-    
             copy
@@ -1719,20 +1719,16 @@
         
-    
 continue
@@ -1729,36 +1729,32 @@
 ntinue%0A%0A        
- 
-   
 # update the met
@@ -1829,31 +1829,70 @@
 ces%0A        
-    try
+try:%0A            if temp_dir and vrt_file_path
 :%0A          
@@ -1949,16 +1949,235 @@
 act meta
+.%0A                # the reason to change current working directory to temp_dir is to make sure the raster files can be%0A                # found by Gdal for metadata extraction when %22relativeToVRT%22 parameter is set as %220%22
 %0A       
@@ -3382,28 +3382,24 @@
 ))%0A%0A        
-    
 except Excep
@@ -3401,36 +3401,32 @@
 Exception as e:%0A
-    
             if o
@@ -3457,36 +3457,32 @@
                 
-  
-  
 shutil.rmtree(te
@@ -3481,36 +3481,32 @@
 mtree(temp_dir)%0A
-    
             log.
@@ -3518,36 +3518,32 @@
 tion(e.message)%0A
-    
             meta

clean up migration code