#! /usr/bin/python3

import sys
import os
import time
import shutil
import datetime
from netCDF4 import Dataset

opath = "/data/noaaport/sat"

def log_write( lfile, message ):
    csecs = time.time()
    times = time.gmtime( csecs )
    datim = time.strftime( "%Y%m%d-%H%M%S", times )
    lfile.write( datim + " " + message+"\n" )

def open_output( ofilename, infile ):
    print( "Outfile: %s" % ofilename )
    if( not os.path.exists( opath )):
        os.mkdir( opath )
    if( not os.path.exists( opath+"/"+odate )):
        os.mkdir( opath+"/"+odate )
    log_write( lfile, "Outfile: %s" % (opath+"/"+ofilename) )
    ofile = Dataset( opath+"/"+odate+"/."+ofilename, "w")
    ofile.title = ifile.title
    ofile.ICD_version = ifile.ICD_version
    ofile.Conventions = ifile.Conventions
    ofile.channel_id = ifile.channel_id
    ofile.central_wavelength = ifile.central_wavelength
    ofile.abi_mode = ifile.abi_mode
    ofile.source_scene = ifile.source_scene
    ofile.periodicity = ifile.periodicity
    ofile.production_location = ifile.production_location
    ofile.product_name = ifile.product_name
    ofile.satellite_id = ifile.satellite_id
    ofile.product_center_latitude = ifile.product_center_latitude
    ofile.product_center_longitude = ifile.product_center_longitude
    ofile.projection = ifile.projection
    ofile.bit_depth = ifile.bit_depth
    ofile.start_date_time = ifile.start_date_time
    ofile.product_rows = ifile.product_rows
    ofile.product_columns = ifile.product_columns
    ofile.pixel_x_size = ifile.pixel_x_size
    ofile.pixel_y_size = ifile.pixel_y_size
    ofile.satellite_latitude = ifile.satellite_latitude
    ofile.satellite_longitude = ifile.satellite_longitude
    ofile.satellite_altitude = ifile.satellite_altitude
    xdim = ofile.createDimension("x", ifile.product_columns )
    ydim = ofile.createDimension("y", ifile.product_rows )

    out_image = ofile.createVariable("Sectorized_CMI", 'i2', ("y", "x"), fill_value = in_image._FillValue )
    out_image.standard_name = in_image.standard_name
    out_image.units = in_image.units
    out_image.grid_mapping = in_image.grid_mapping
    out_image.add_offset = in_image.add_offset
    out_image.scale_factor = in_image.scale_factor
    out_image.valid_min = in_image.valid_min
    out_image.valid_max = in_image.valid_max
    out_y = ofile.createVariable("y", 'i2', ("y"))
    out_y.standard_name = in_y.standard_name
    out_y.units = in_y.units
    out_y.scale_factor = in_y.scale_factor
    out_y.add_offset = in_y.add_offset
    out_x = ofile.createVariable("x", 'i2', ("x"))
    out_x.standard_name = in_x.standard_name
    out_x.units = in_x.units
    out_x.scale_factor = in_x.scale_factor
    out_x.add_offset = in_x.add_offset
    if( in_image.grid_mapping == "lambert_projection" ):
        proj = ofile.createVariable("lambert_projection", 'i4')
        proj.grid_mapping_name = in_proj.grid_mapping_name
        proj.standard_parallel = in_proj.standard_parallel
        proj.longitude_of_central_meridian = in_proj.longitude_of_central_meridian
        proj.latitude_of_projection_origin = in_proj.latitude_of_projection_origin
        proj.false_easting = in_proj.false_easting
        proj.false_northing = in_proj.false_northing
        proj.semi_major = in_proj.semi_major
        proj.semi_minor = in_proj.semi_minor
    if( in_image.grid_mapping == "mercator_projection" ):
        proj = ofile.createVariable("mercator_projection", 'i4')
        proj.grid_mapping_name = in_proj.grid_mapping_name
        proj.standard_parallel = in_proj.standard_parallel
        proj.longitude_of_projection_origin = in_proj.longitude_of_projection_origin
        proj.false_easting = in_proj.false_easting
        proj.false_northing = in_proj.false_northing
        proj.semi_major = in_proj.semi_major
        proj.semi_minor = in_proj.semi_minor
    if( in_image.grid_mapping == "fixedgrid_projection" ):
        proj = ofile.createVariable("fixedgrid_projection", 'i4')
        proj.grid_mapping_name = in_proj.grid_mapping_name
        proj.latitude_of_projection_origin = in_proj.latitude_of_projection_origin
        proj.longitude_of_projection_origin = in_proj.longitude_of_projection_origin
        if( hasattr( in_proj, "semi_major" )):
            proj.semi_major = in_proj.semi_major
        else :
            proj.semi_major = in_proj.semi_major_axis
        if( hasattr( in_proj, "semi_minor" )):
            proj.semi_minor = in_proj.semi_minor
        else :
            proj.semi_minor = in_proj.semi_minor_axis
        proj.perspective_point_height = in_proj.perspective_point_height
        proj.sweep_angle_axis = in_proj.sweep_angle_axis
    out_image.set_auto_scale( False )
    out_x.set_auto_scale( False )
    out_y.set_auto_scale( False )
    return ofile

csecs = time.time()
times = time.gmtime( csecs )
datim = time.strftime( "%Y%m%d", times )
lfile = open( "/home/ldm/var/logs/composite_goes-"+datim+".log", "a" )

if( len(sys.argv) == 2 ):
    filename = sys.argv[1]
    print( "Opening %s" % filename )
    log_write( lfile, "Opening %s" % filename )
    ifile = Dataset( filename )

    nx = ifile.dimensions['x'].size
    ny = ifile.dimensions['y'].size

    sdatim = datetime.datetime.strptime( ifile.start_date_time, "%Y%j%H%M%S" )

    in_image = ifile.variables['Sectorized_CMI']
    in_y = ifile.variables['y']
    in_x = ifile.variables['x']
    if( in_image.grid_mapping == "lambert_projection" ):
        in_proj = ifile.variables['lambert_projection']
    if( in_image.grid_mapping == "mercator_projection" ):
        in_proj = ifile.variables['mercator_projection']
    if( in_image.grid_mapping == "fixedgrid_projection" ):
        in_proj = ifile.variables['fixedgrid_projection']

    sat = "g16"
    if( ifile.satellite_id == "GOES-17" ):
        sat = "g17"
    opath = opath+"/"+sat
    reg = "us"
    # :product_name = "EFD-060-B12-M4C02" ;
    if( ifile.product_name[0:3] == "EFD" ):
        reg = "full"

    ch = "ch%2.2d"%ifile.channel_id
    if( ifile.channel_id == 1 ):
        ch = "vib"
    elif( ifile.channel_id == 2 ):
        ch = "vir"
    elif( ifile.channel_id == 3 ):
        ch = "nirv"
    elif( ifile.channel_id == 4 ):
        ch = "nirc"
    elif( ifile.channel_id == 8 ):
        ch = "wvu"
    elif( ifile.channel_id == 9 ):
        ch = "wv"
    elif( ifile.channel_id == 10 ):
        ch = "wvl"
    elif( ifile.channel_id == 14 ):
        ch = "ir"
    odate = sdatim.strftime( "%Y%m%d" )
    ofilename = sdatim.strftime( "%Y%m%d_%H%M_"+sat+"_"+reg+"_"+ch+".nc" )
    ofile = open_output( ofilename, ifile )
    tiles = ifile.number_product_tiles
    #print "Tiles: %d" % tiles
    im_found = [False for i in range(tiles)]
    total_found = 0
    ifile.close() 
    for t in range( 28 ):
        for i in range( tiles ):
            if( im_found[i] ):
                continue
            #print "Tile: %d" % (i+1)
            i1 = chr(int(i/26)+ord('A'))
            i2 = chr(int(i%26)+ord('A'))
            ifilename = filename.replace( "PAA", "P"+i1+i2 )
            #print ifilename
            if( not os.path.isfile( ifilename )):
                continue
            print( "Found: %d" % (i+1))
            log_write( lfile, "Found: %d" % (i+1))
            total_found += 1
            im_found[i] = True
            ifile = Dataset( ifilename )
    
            nx = ifile.product_tile_width
            ny = ifile.product_tile_height
            ox = ifile.tile_column_offset
            oy = ifile.tile_row_offset
            print( "Size %d x %d at %d, %d" % (nx, ny, ox, ny ))
            in_image.set_auto_scale( False )
            in_x.set_auto_scale( False )
            in_y.set_auto_scale( False )
            out_image = ofile.variables['Sectorized_CMI']
            out_y = ofile.variables['y']
            out_x = ofile.variables['x']
            out_image[oy:oy+ny,ox:ox+nx] = in_image[:]
            out_y[oy:oy+ny] = in_y[:]
            out_x[ox:ox+nx] = in_x[:]
            ifile.close() 
        if( total_found == tiles ):
            break
        time.sleep( 15 )
        log_write( lfile, "Not done, waiting..." )
    log_write( lfile, "Done writing "+ofilename+" , processed %d of %d" % ( total_found, tiles ))
    ofile.close()

else :
    for i in range( 1, len(sys.argv)):
        filename = sys.argv[i]
        print( "Opening %s" % filename )
        ifile = Dataset( filename )
    
        nx = ifile.dimensions['x'].size
        ny = ifile.dimensions['y'].size
    
        sdatim = datetime.datetime.strptime( ifile.start_date_time, "%Y%j%H%M%S" )
        odate = sdatim.strftime( "%Y%m%d" )
    
        in_image = ifile.variables['Sectorized_CMI']
        in_y = ifile.variables['y']
        in_x = ifile.variables['x']
        if( in_image.grid_mapping == "lambert_projection" ):
            in_proj = ifile.variables['lambert_projection']
        if( in_image.grid_mapping == "mercator_projection" ):
            in_proj = ifile.variables['mercator_projection']
        if( in_image.grid_mapping == "fixedgrid_projection" ):
            in_proj = ifile.variables['fixedgrid_projection']
    
        if( i == 1 ):
            reg = "us"
            if( ifile.source_scene == "FullDisk" ):
                reg = "full"
            ch = "ch%2.2d"%ifile.channel_id
            if( ifile.channel_id == 1 ):
                ch = "vib"
            elif( ifile.channel_id == 2 ):
                ch = "vir"
            elif( ifile.channel_id == 14 ):
                ch = "ir"
            ofilename = sdatim.strftime( "%Y%m%d_%H%M_"+sat+"_"+reg+"_"+ch+".nc" )
            ofile = open_output( ofilename, ifile )
    
        #print var
        nx = ifile.product_tile_width
        ny = ifile.product_tile_height
        ox = ifile.tile_column_offset
        oy = ifile.tile_row_offset
        print( "Size %d x %d at %d, %d" % (nx, ny, ox, ny ))
        #in_image.set_auto_scale( False )
        out_image = ofile.variables['Sectorized_CMI']
        out_y = ofile.variables['y']
        out_x = ofile.variables['x']
        out_image[oy:oy+ny,ox:ox+nx] = in_image[:]
        out_y[oy:oy+ny] = in_y[:]
        out_x[ox:ox+nx] = in_x[:]
    ofile.close()


shutil.move( opath+"/"+odate+"/."+ofilename, opath+"/"+odate+"/"+ofilename )
ldmfilename = "/tmp/"+ofilename
ldmfile = open( ldmfilename, "w" )
ldmfile.write( ofilename )
ldmfile.close()
os.system( "/home/ldm/bin/pqinsert -f OTHER -p \"AVAIL SATIMG "+ofilename+"\" "+ldmfilename )
log_write( lfile, "Composite done: %s" % ofilename )
os.unlink( ldmfilename )
