import os, os.path
import shlex
import subprocess
from datetime import datetime, timedelta, time
import numpy as np

from nansat import Nansat

class MerisImage(Nansat):
    '''
    Read parameters from MERIS file
    '''
    
    def __init__(self, fileName, logLevel=30):
        '''
        Read attributes from file name
        MER_FRS_1PNPDE20110823_105011_000002423105_00425_49577_1653.N1
        Read lat/lon
        '''
        #init nansat object (open GDAL dataset, get mapper, etc) add new
        #functions
        Nansat.__init__(self, fileName, logLevel=logLevel);
        
        #get start/stop/diff datetime from metadata
        self.dateStart = self.get_time()[0]
        self.dateStop  = datetime(1,1,1).strptime(self.get_metadata('SPH_LAST_LINE_TIME').lower(), '%d-%b-%Y %H:%M:%S.%f')            

        self.dateDiff = timedelta(0);
        self.dateDiff = self.dateStop - self.dateStart;
        
        #set values to the metadata data where it is availabe for ImagesCatalog
        self.set_metadata('name',       "'%s'" % self.name)
        self.set_metadata('path',       "'%s'" % self.path)
        self.set_metadata('sensor',     "'meris'")            
        self.set_metadata('resolution', "'%s'" % self.name[4:6])
        self.set_metadata('level',      self.name[8:9])
        self.set_metadata('sensstart',  "'%s'" % self.dateStart.strftime('%Y-%m-%d %H:%M:%S.%f'))
        self.set_metadata('sensend',    "'%s'" % self.dateStop.strftime('%Y-%m-%d %H:%M:%S.%f'))          
        self.set_metadata('orbit',      self.get_metadata('MPH_ABS_ORBIT'))
        self.set_metadata('border',   self.get_border_postgis())

    def subimage(self, start=0, end=1):
        '''Substract part of the image into a seperate file using PdsSubset'''
        pdsSubsetCmd = '/usr/local/bin/PdsSubset'
        
        #which timedeltas correspond to nothermost and southernmost rows (only for each 64th line)
        #dateDiff in microseconds
        dateDiffMS = self.dateDiff.seconds * 10**6 + self.dateDiff.microseconds
        #values of dateDiff for each lat/lon line (OR each 64 raw lines [0.043997 sec/line])
        microStep = 64 * 10**6 * 0.043997;
        diffVecMS = np.arange(0, dateDiffMS + 2*microStep, microStep) - 1
        print '64-lines stripes:', len(diffVecMS)
        
        firstDiffI = int(start*len(diffVecMS))
        lastDiffI = int(end*len(diffVecMS))
        print 'diff indeces: %d - %d' % (firstDiffI, lastDiffI)
        
        #dateDiff for first row
        dtFirst = timedelta(0, 0, diffVecMS[firstDiffI]);
        #dateDiff for last row
        dtLast = timedelta(0, 0, diffVecMS[lastDiffI]);

        #call PdsSubset
        cmdString = '%s -out %s -starttime %s -stoptime %s %s%s' %  (
            pdsSubsetCmd, self.path,
            (self.dateStart + dtFirst).strftime('%d-%b-%Y %H:%M:%S.%f').upper(),
            (self.dateStart + dtLast).strftime('%d-%b-%Y %H:%M:%S.%f').upper(),
            self.path, self.fileName)
        cmdList = shlex.split(cmdString) 
        print cmdString

        p = subprocess.Popen(cmdList, stdout=subprocess.PIPE)
        p.wait()

        #rename output file (place proper orbit name)
        pLines = p.stdout.readlines()
        oFile = pLines[-1].split()[-1].split('/')[-1]
        oFile2 = oFile.replace(oFile[49:54], self.fileName[49:54])
        os.rename(self.path+oFile, self.path+oFile2)
        print self.path+oFile2
        
        #return on success
        return 0

    """
    def subimage(self, zPolygon, zName):
        '''Substract part of the image into a seperate file using PdsSubset'''
        pdsSubsetCmd = '/usr/local/bin/PdsSubset'
        
        #try to make subfolder to keep the image
        oDir = self.path + zName + '/';
        if not os.path.exists(oDir):
            try:
                print 'Creating %s ...' % oDir,
                os.mkdir(oDir)
            except:
                print '...failed'
                oDir = self.path
        
        print 'Output to %s' % oDir;

        #which timedeltas correspond to nothermost and southernmost rows (only for each 64th line)
        #dateDiff in microseconds
        dateDiffMS = self.dateDiff.seconds * 10**6 + self.dateDiff.microseconds
        #values of dateDiff for each lat/lon line (OR each 64 raw lines [0.043997 sec/line])
        microStep = 64 * 10**6 * 0.043997;
        diffVecMS = np.arange(0, dateDiffMS + 2*microStep, microStep) - 1
        print '64-lines stripes:', len(diffVecMS)
       
        t1 = time.time()
        #get list corners [lon,lat)] from input WKT polygon
        corners = zPolygon.split('(',)[-1].split(')')[0].split(',')
        corners = [[float(cc) for cc in c.split()] for c in corners]
        
        #which rows correspond to nothermost and southernmost corners
        rows = [];
        cols = [];
        for corner in corners:
            distGrid = np.square(self.lonGrid-corner[0])+np.square(self.latGrid-corner[1])
            rows.append(np.nonzero(distGrid == np.min(distGrid.flat))[0][0])
            cols.append(np.nonzero(distGrid == np.min(distGrid.flat))[1][0])
            
        #get first-10 and last+10 rows and columns (insure inside boundary)
        print 'MIN/MAX R/C', min(rows), max(rows), min(cols), max(cols)
        rowFirst = max(0, min(rows)-10)
        rowLast = min(len(diffVecMS)-1, max(rows)+10)
        colLeft = max(0, min(cols)-10);
        colRight = min(self.lonGrid.shape[1]-1, max(cols)+10);
        print 'R/C, F/L/M:', rowFirst, rowLast, self.lonGrid.shape[0], ' | ', colLeft, colRight, self.lonGrid.shape[1], 
        if (rowLast <= 3) or (colRight <= 3) or (self.lonGrid.shape[0] - rowFirst) <= 3 or (self.lonGrid.shape[1] - colLeft) <= 3:
            print 'Nothing to substract in ', self.iFile;
            return -1
        else:
            print
        
        #dateDiff for first row
        dtFirst = timedelta(0, 0, diffVecMS[rowFirst]);
        #dateDiff for last row
        dtLast = timedelta(0, 0, diffVecMS[rowLast]);

        #call PdsSubset
        cmdString = '%s -out %s -starttime %s -stoptime %s %s%s' %  (
            pdsSubsetCmd, oDir,
            (self.dateStart + dtFirst).strftime('%d-%b-%Y %H:%M:%S.%f').upper(),
            (self.dateStart + dtLast).strftime('%d-%b-%Y %H:%M:%S.%f').upper(),
            self.iDir, self.iFile)
        cmdList = shlex.split(cmdString) 
        print cmdString

        p = subprocess.Popen(cmdList, stdout=subprocess.PIPE)
        p.wait()
        
        #rename output file (place proper orbit name)
        pLines = p.stdout.readlines()
        oFile = pLines[-1].split()[-1].split('/')[-1]
        oFile2 = oFile.replace(oFile[49:54], self.iFile[49:54])
        os.rename(oDir+oFile, oDir+oFile2)
        print oDir+oFile2, time.time() - t1;
        
        #return on success
        return 0
    """
    
    def process_web(self, opts=None):
        '''
        NRT Processing of Radarsat includes:
            Visualisation of small quick look
            Visualisation of large quick look
            Generating map
            Input:
            ------
            opts: dictionary with processing options
            '''
        oBaseFileName = self.get_metadata('name').strip('"').strip("'")
        qlName = opts['mapDir'] + '/' + oBaseFileName + '_.jpg'
        mapName = opts['mapDir'] + oBaseFileName + '_.png'
        # 1. Generate small quicklook
        if not os.path.exists(qlName):
            self.resize(width=300)
            try:
                self.write_figure(qlName, clim='hist', ratio=0.9)
            except:
                self.logger.error('Cannot write preview of %s' % self.fileName)
            self.resize()

        # 3. Generate map
        if not os.path.exists(mapName):
            self.write_map(mapName)

        return 0
