#! /usr/bin/env python3
# -*- coding: iso-8859-15 -*-

from optparse import OptionParser
import hashlib
import os.path
from glob import glob
import numpy as np
from astropy.io import fits
from astropy.table import Table


def fits2table(path, keys, constraints={}):
    """
    Convert headers item of FITS files on path to table.

    Parameters
    ----------
    path: string
        Path with pattern to select fits files.
    keys: list
        List of strings specifying the header keyword to convert.
    constraints: dict
        Constraints to apply to the header values.
        Dictionary keys are the header keywords, dictionary values are the constraints.

    Returns
    -------
    table: astropy.table.Table
        Table where each row corresponds to an accepted fits file,
        and where the columns correspond to the requested keys.
    """

    merged_keys = list(keys)
    for key in constraints:
        if key not in merged_keys:
            merged_keys.append(key)
    data = {}
    data['filename'] = []
    for key in merged_keys:
        data[key] = []
    filenames = glob(path)
    filenames.sort()
    for filename in filenames:
        data['filename'].append(filename.rsplit('/',1)[-1])
        with fits.open(filename) as hdulist:
            for key in merged_keys:
                if key in hdulist[0].header:
                    data[key].append(hdulist[0].header[key])
                else:
                    data[key].append("")
    tbl = Table(data, names=('filename',)+tuple(merged_keys))
    mask = np.array([True]*len(tbl))
    for key in constraints:
        if type(constraints[key]) is list:
            m = np.array([False]*len(tbl[key]))
            for c in constraints[key]:
                m |= (tbl[key] == c)
            mask &= m
        else:
            mask = mask & (tbl[key] == constraints[key])
    return tbl[mask]


def inventory(path):
    pattern = "*GRAVI*.fits"
    tbl = fits2table(os.path.join(path, pattern), ['ESO TPL ID', 'ESO TPL EXPNO', 'ESO DPR TYPE', 'ESO DPR TECH', 'ESO FT ROBJ NAME', 'ESO INS SOBJ NAME', 'ESO DPR CATG', 'ESO INS SPEC RES', 'ESO DET2 SEQ1 DIT', 'ESO INS SOBJ X', 'ESO INS SOBJ Y'])
    # Remove ESO from column headers, to save space
    for name in tbl.colnames:
        items = name.split(" ", 1)
        if items[0] == "ESO":
            tbl.rename_column(name, items[1])
    return tbl


if __name__ == "__main__":

    usage = """
            usage:  %prog [options]

            Run inventory.
    """

    parser = OptionParser(usage)

    parser.add_option("-p", "--path", dest="path", default=".",
                      help="Inventory directory")

    (options, args) = parser.parse_args()

    inventory(options.path).pprint(max_lines=-1, max_width=-1)
