#!/usr/bin/env python3

# Copyright (C) 2019 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1.  Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
# 2.  Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import sys
sys.dont_write_bytecode = True

import argparse
import os
import sys
import unittest

from cassandra.cqlengine.management import CQLENG_ALLOW_SCHEMA_MANAGEMENT

def main():
    parser = argparse.ArgumentParser(description='Run unit tests for resultsdbpy')
    parser.add_argument('-v', '--verbose',
                      default=False, action='store_true',
                      help='Verbose output')
    parser.add_argument('--stop-on-fail',
                      default=False, action='store_true',
                      help='Stop on first fail or error')
    parser.add_argument('modules_to_test', nargs='*',
                      help='Modules to be tested. By default, this is the database, flask_support, model and view modules',
                      default=['controller', 'flask_support', 'model', 'view'])
    parser.add_argument('-f', '--fast-tests',
                      default=False, action='store_true',
                      help='Some tests require a docker instance and are slow, optionally skip these')
    parser.add_argument('--no-web-server',
                        dest='web_server', default=True, action='store_false',
                        help='Some tests use a Flask webserver, optionally skip these')
    parser.add_argument('--no-selenium',
                        dest='selenium', default=True, action='store_false',
                        help='Some tests use Selenium to test the UI of the site, optionally skip these')
    options = parser.parse_args()

    os.environ['slow_tests'] = '0' if options.fast_tests else '1'
    os.environ['web_server'] = '1' if options.web_server else '0'
    os.environ['selenium'] = '1' if options.selenium else '0'
    os.environ[CQLENG_ALLOW_SCHEMA_MANAGEMENT] = '1'

    root = os.path.dirname(os.path.abspath(__file__))

    suite = unittest.TestSuite()
    for module_name in options.modules_to_test:
        module_suite = unittest.defaultTestLoader.discover(os.path.join(root, module_name.replace('.', '/')), pattern='*unittest.py', top_level_dir=os.path.join(root, '..'))
        for tst in module_suite if module_suite else []:
            suite.addTest(tst)

    if suite.countTestCases() == 0:
        raise RuntimeError('No tests matching...')

    result = unittest.TextTestRunner(verbosity=2 if options.verbose else 1, failfast=options.stop_on_fail, buffer=not options.verbose).run(suite)
    return len(result.errors)

if __name__ == '__main__':
    sys.exit(main())
