#!/usr/bin/env python
"""
Copyright 2015 ARC Centre of Excellence for Climate Systems Science

author: Scott Wales <scott.wales@unimelb.edu.au>

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

from sqlalchemy import Column, Integer, String, Boolean, ForeignKey, Date, UniqueConstraint
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base

import os
import glob

Base = declarative_base()

class Instance(Base):
    """
    A model variable from a specific run

    Search through these using :func:`ARCCSSive.CMIP5.Session.outputs()`

    .. attribute:: variable

        Variable name

    .. attribute:: experiment

        CMIP experiment

    .. attribute:: mip

        MIP table specifying output frequency

    .. attribute:: model

        Model that generated the dataset

    .. attribute:: ensemble

        Ensemble member

    .. attribute:: versions

        List of :class:`Version` available for this output
    """
    __tablename__ = 'instances'
    id         = Column(Integer, name='instance_id', primary_key = True)

    variable   = Column(String, index=True)
    experiment = Column(String, index=True)
    mip        = Column(String, index=True)
    model      = Column(String, index=True)
    ensemble   = Column(String)
    realm      = Column(String)
    #latest     = Column(String)
    #drstree    = Column(String)
    # these last two are replaced by functions
    # there will be new versions labelled 've' (version estimate) in drstree so using only timestamp to order them

    versions   = relationship('Version', order_by='Version.version', backref='variable')

    __table_args__ = (
            UniqueConstraint('variable','experiment','mip','model','ensemble'),
            )

    def filenames(self):
        """
        Returns the file names from the latest version of this variable

        :returns: List of file names
        """
        #return self.versions[-1].filenames()
        if not self.versions[-1].is_latest: print "Warning this is the latest version on raijin but not the latest published"
#PA need to add to this the path!!
        return self.versions[-1].files

    def drstree_path(self):
        """ 
        Returns the drstree path for this instance, if one is not yet available returns None 
        """
        drstreep="/g/data1/ua6/drstree/CMIP5/GCM/" # this should be passed as DRSTREE env var
        return DRSTREE + "/".join( self.model, 
                                   self.experiment,
                                   self.frequency,
                                   self.realm,
                                   self.variable,
                                   self.ensemble) 

# Add alias to deprecated name
Variable = Instance

class Version(Base):
    """
    A version of a model run's variable

    .. attribute:: version

        Version identifier

    .. attribute:: path

        Path to the output directory

    .. attribute:: variable

        :class:`Variable` associated with this version

    .. attribute:: warnings

        List of :class:`VersionWarning` available for this output

    .. attribute:: files

        List of :class:`VersionFile` available for this output
    """
    __tablename__ = 'versions'
    id          = Column(Integer, name='version_id', primary_key = True)
    instance_id = Column(Integer, ForeignKey('instances.instance_id'))

    version     = Column(String)
    path        = Column(String)
    dataset_id  = Column(String)
    is_latest   = Column(Boolean)
    checked_on  = Column(String)
    to_update   = Column(Boolean)

    warnings   = relationship('VersionWarning', order_by='VersionWarning.id', backref='version')
    files   = relationship('VersionFile', order_by='VersionFile.id', backref='version')

    def glob(self):
        """ Get the glob string matching the CMIP5 filename
        """
        return '%s_%s_%s_%s_%s*.nc'%(
            self.variable.variable,
            self.variable.mip,
            self.variable.model,
            self.variable.experiment,
            self.variable.ensemble)

    def filenames(self):
        """
        Returns the list of files matching this version

        :returns: List of file names
        """
        g = os.path.join(self.path, self.glob())
        return glob.glob(g)
         
    def filenames2(self):
        """
        Returns the list of files matching this version

        :returns: List of file names
        """
        return [x.filename for x in self.files] 
         

    def tracking_ids(self):
        """
        Returns the list of tracking_ids for files in this version

        :returns: List of tracking_ids
        """
        return [x.tracking_id for x in self.files] 
        
class VersionWarning(Base):
    """
    Warnings associated with a output version
    """
    __tablename__ = 'warnings'

    id         = Column(Integer, name='warning_id', primary_key = True)
    warning    = Column(String)
    added_by   = Column(String)
    added_on   = Column(Date)
    version_id = Column(Integer, ForeignKey('versions.version_id'))

    def __str__(self):
        return u'%s (%s): %s'%(self.added_on, self.added_by, self.warning) 


class VersionFile(Base):
    """
    Files associated with a output version
    """
    __tablename__ = 'files'

    id           = Column(Integer, name='file_id', primary_key = True)
    filename     = Column(String)
    tracking_id  = Column(String)
    md5          = Column(String)
    sha256       = Column(String)
    version_id   = Column(Integer, ForeignKey('versions.version_id'))

    def __str__(self):
        return '%s'%(self.filename)

@@ -667,16 +667,54 @@
 e.%0A%22%22%22%0A%0A
+from __future__ import print_function%0A
 from sql
@@ -2524,17 +2524,17 @@
 t: print
- 
+(
 %22Warning
@@ -2600,16 +2600,17 @@
 blished%22
+)
 %0A#PA nee

Use Python3-style print