#!/usr/bin/env python2

# THIS FILE IS PART OF THE CYLC SUITE ENGINE.
# Copyright (C) 2008-2018 NIWA & British Crown (Met Office) & Contributors.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

"""cylc [prep] print [OPTIONS] [REGEX]

Print registered (installed) suites.

Note on result filtering:
  (a) The filter patterns are Regular Expressions, not shell globs, so
the general wildcard is '.*' (match zero or more of anything), NOT '*'.
  (b) For printing purposes there is an implicit wildcard at the end of
each pattern ('foo' is the same as 'foo/*'); use the string end marker
to prevent this ('foo$' matches only literal 'foo')."""

import sys
from cylc.remote import remrun
if remrun():
    sys.exit(0)

import os
import re

import cylc.flags
from cylc.option_parsers import CylcOptionParser as COP
from cylc.suite_srv_files_mgr import SuiteSrvFilesManager
from cylc.print_tree import print_tree


def get_padding(reglist):
    maxlen = 0
    for reg in reglist:
        items = reg[0].split(SuiteSrvFilesManager.DELIM)
        for i in range(0, len(items)):
            if i == 0:
                tmp = len(items[i])
            else:
                tmp = 2 * i + 1 + len(items[i])
            if tmp > maxlen:
                maxlen = tmp
    return maxlen * ' '


def main():
    parser = COP(__doc__,
                 argdoc=[('[REGEX]', 'Suite name regular expression pattern')])

    parser.add_option(
        "-t", "--tree", help="Print suites in nested tree form.",
        action="store_true", default=False, dest="tree")

    parser.add_option(
        "-b", "--box",
        help="Use unicode box drawing characters in tree views.",
        action="store_true", default=False, dest="unicode")

    parser.add_option(
        "-a", "--align", help="Align columns.",
        action="store_true", default=False, dest="align")

    parser.add_option(
        "-x", help="don't print suite definition directory paths.",
        action="store_true", default=False, dest="x")

    parser.add_option(
        "-y", help="Don't print suite titles.",
        action="store_true", default=False, dest="y")

    parser.add_option(
        "--fail", help="Fail (exit 1) if no matching suites are found.",
        action="store_true", default=False, dest="fail")

    (options, args) = parser.parse_args()

    regfilter = None
    if args:
        regfilter = args[0]

    suite_src_files_mgr = SuiteSrvFilesManager()
    allsuites = suite_src_files_mgr.list_suites(regfilter)
    if options.fail and not allsuites:
        raise SystemExit('ERROR: no suites matched.')
    if not options.tree:
        if options.align:
            maxlen_suite = 0
            maxlen_title = 0
            for suite, dir_, title in allsuites:
                if len(suite) > maxlen_suite:
                    maxlen_suite = len(suite)
                if len(title) > maxlen_title:
                    maxlen_title = len(title)
            spacer_suite = maxlen_suite * ' '
            spacer_title = maxlen_title * ' '
        for suite, dir_, title in allsuites:
            dir_ = re.sub('^' + os.environ['HOME'], '~', dir_)
            if options.align:
                suite = suite + spacer_suite[len(suite):]
                title = title + spacer_title[len(title):]
            if not options.x and not options.y:
                line = suite + ' | ' + title + ' | ' + dir_
            elif not options.y:
                line = suite + ' | ' + title
            elif not options.x:
                line = suite + ' | ' + dir_
            else:
                line = suite
            print line
    else:
        tree = {}
        if options.align:
            maxlen_title = 0
            for suite, dir_, title in allsuites:
                if len(title) > maxlen_title:
                    maxlen_title = len(title)
            spacer_title = maxlen_title * ' '

        for suite, dir_, title in allsuites:
            dir_ = re.sub('^' + os.environ['HOME'], '~', dir_)
            if options.align:
                title = title + spacer_title[len(title):]
            regpath = suite.split(SuiteSrvFilesManager.DELIM)
            sub = tree
            for key in regpath[:-1]:
                if key not in sub:
                    sub[key] = {}
                sub = sub[key]
            if not options.x and not options.y:
                line = title + ' | ' + dir_
            elif not options.y:
                line = ' ' + title
            elif not options.x:
                line = ' ' + dir_
            else:
                line = ''
            sub[regpath[-1]] = line

        pad = get_padding(allsuites)
        print_tree(tree, pad, options.unicode)


if __name__ == "__main__":
    try:
        main()
    except Exception as exc:
        if cylc.flags.debug:
            raise
        sys.exit(str(exc))
