#!/usr/bin/env python3

# Copyright (C) 2019-2021 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

import resultsdbpy
from webkitcorepy import AutoInstall

libraries = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if sys.platform == 'darwin':
    is_root = not os.getuid()
    does_own_libraries = os.stat(libraries).st_uid == os.getuid()
    if (is_root or not does_own_libraries):
        libraries = os.path.expanduser('~/Library/webkitpy')
AutoInstall.set_directory(os.path.join(libraries, 'autoinstalled', 'python-{}'.format(sys.version_info[0])))

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, 'resultsdbpy', 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())
