# Licensed under a 3-clause BSD style license - see LICENSE.rst
"""
``showtable`` is a command-line script based on ``astropy.io`` and
``astropy.table`` for printing ASCII, FITS, HDF5 or VOTable files(s) to the
standard output.

Example usage of ``showtable``:

1. FITS::

    $ showtable astropy/io/fits/tests/data/table.fits

     target V_mag
    ------- -----
    NGC1001  11.1
    NGC1002  12.3
    NGC1003  15.2

2. ASCII::

    $ showtable astropy/io/ascii/tests/t/simple_csv.csv

     a   b   c
    --- --- ---
      1   2   3
      4   5   6

3. XML::

    $ showtable astropy/io/votable/tests/data/names.xml --max-width 70

               col1             col2     col3  ... col15 col16 col17
               ---              deg      deg   ...  mag   mag   ---
    ------------------------- -------- ------- ... ----- ----- -----
    SSTGLMC G000.0000+00.1611   0.0000  0.1611 ...    --    --    AA



4. Print all the FITS tables in the current directory::

    $ showtable *.fits

"""

import argparse
import textwrap
import warnings
from astropy import log
from astropy.table import Table
from astropy.utils.exceptions import AstropyUserWarning


def showtable(filename, args):
    """
    Read a table and print to the standard output.

    Parameters
    ----------
    filename : str
        The path to a FITS file.

    """
    if args.info and args.stats:
        warnings.warn('--info and --stats cannot be used together',
                      AstropyUserWarning)
    if (any((args.max_lines, args.max_width, args.hide_unit, args.show_dtype))
            and (args.info or args.stats)):
        warnings.warn('print parameters are ignored if --info or --stats is '
                      'used', AstropyUserWarning)

    # these parameters are passed to Table.read if they are specified in the
    # command-line
    read_kwargs = ('hdu', 'format', 'table_id', 'delimiter')
    kwargs = {k: v for k, v in vars(args).items()
              if k in read_kwargs and v is not None}
    try:
        table = Table.read(filename, **kwargs)
        if args.info:
            table.info('attributes')
        elif args.stats:
            table.info('stats')
        else:
            formatter = table.more if args.more else table.pprint
            formatter(max_lines=args.max_lines, max_width=args.max_width,
                      show_unit=(False if args.hide_unit else None),
                      show_dtype=(True if args.show_dtype else None))
    except OSError as e:
        log.error(str(e))


def main(args=None):
    """The main function called by the `showtable` script."""
    parser = argparse.ArgumentParser(
        description=textwrap.dedent("""
            Print tables from ASCII, FITS, HDF5, VOTable file(s).  The tables
            are read with 'astropy.table.Table.read' and are printed with
            'astropy.table.Table.pprint'. The default behavior is to make the
            table output fit onto a single screen page.  For a long and wide
            table this will mean cutting out inner rows and columns.  To print
            **all** the rows or columns use ``--max-lines=-1`` or
            ``max-width=-1``, respectively. The complete list of supported
            formats can be found at
            http://astropy.readthedocs.io/en/latest/io/unified.html#built-in-table-readers-writers
        """))

    addarg = parser.add_argument
    addarg('filename', nargs='+', help='path to one or more files')

    addarg('--format', help='input table format, should be specified if it '
           'cannot be automatically detected')
    addarg('--more', action='store_true',
           help='use the pager mode from Table.more')
    addarg('--info', action='store_true',
           help='show information about the table columns')
    addarg('--stats', action='store_true',
           help='show statistics about the table columns')

    # pprint arguments
    pprint_args = parser.add_argument_group('pprint arguments')
    addarg = pprint_args.add_argument
    addarg('--max-lines', type=int,
           help='maximum number of lines in table output (default=screen '
           'length, -1 for no limit)')
    addarg('--max-width', type=int,
           help='maximum width in table output (default=screen width, '
           '-1 for no limit)')
    addarg('--hide-unit', action='store_true',
           help='hide the header row for unit (which is shown '
           'only if one or more columns has a unit)')
    addarg('--show-dtype', action='store_true',
           help='always include a header row for column dtypes '
           '(otherwise shown only if any column is multidimensional)')

    # ASCII-specific arguments
    ascii_args = parser.add_argument_group('ASCII arguments')
    addarg = ascii_args.add_argument
    addarg('--delimiter', help='column delimiter string')

    # FITS-specific arguments
    fits_args = parser.add_argument_group('FITS arguments')
    addarg = fits_args.add_argument
    addarg('--hdu', help='name of the HDU to show')

    # HDF5-specific arguments
    hdf5_args = parser.add_argument_group('HDF5 arguments')
    addarg = hdf5_args.add_argument
    addarg('--path', help='the path from which to read the table')

    # VOTable-specific arguments
    votable_args = parser.add_argument_group('VOTable arguments')
    addarg = votable_args.add_argument
    addarg('--table-id', help='the table to read in')

    args = parser.parse_args(args)

    for idx, filename in enumerate(args.filename):
        if idx > 0:
            print()
        showtable(filename, args)
