#!/usr/bin/env python

# THIS FILE IS PART OF THE CYLC SUITE ENGINE.
# Copyright (C) 2008-2016 NIWA
#
# 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 [db] refresh [OPTIONS] ARGS

Check a suite database for invalid registrations (no suite definition
directory or suite.rc file) and refresh suite titles in case they have
changed since the suite was registered. Explicit wildcards must be
used in the match pattern (e.g. 'f' will not match 'foo.bar' unless
you use 'f.*')."""

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

import cylc.flags
from cylc.option_parsers import CylcOptionParser as COP
from cylc.registration import RegistrationDB, RegistrationError
from cylc.config import SuiteConfigError
from cylc.regpath import RegPath


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

    parser.add_option(
        "-u", "--unregister",
        help="Automatically unregister invalid registrations.",
        action="store_true", default=False, dest="unregister")

    (options, args) = parser.parse_args()

    db = RegistrationDB(options.db)

    if len(args) == 0:
        pattern = '.*'
    else:
        pattern = args[0]
        # force explicit wildcards
        if not pattern.startswith('^'):
            pattern = '^' + pattern
        if not pattern.endswith('$'):
            pattern += '$'

    invalid = []  # no suite.rc file
    readerror = []  # can't read title (suite.rc parse error)

    # check validity
    invalid = db.get_invalid()
    # refresh titles
    changed = []
    items = db.get_list(pattern)
    if len(items) == 0:
        if pattern:
            print 'No suites found to match', pattern
        else:
            print 'No suites found'
    for suite, dir, title in items:
        if suite in invalid:
            continue
        try:
            db.refresh_suite_title(suite)
        except (RegistrationError, SuiteConfigError), x:
            print >> sys.stderr, x
            readerror.append(suite)
    if len(invalid) > 0:
        print("ERROR, %d invalid registrations "
              "(no suite.rc file):" % len(invalid))
        for i in invalid:
            if options.unregister:
                db.unregister(i)
            else:
                print ' -', i
    if len(readerror) > 0:
        print("ERROR, %d title parse failures "
              "(bad suite.rc file):" % len(readerror))
        for i in readerror:
            print ' -', i


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