# -*- coding: utf-8 -*-
"""Testing framework module for running tests in Python unittest fashion

Copyright (C) 2014 by the GRASS Development Team
This program is free software under the GNU General Public
License (>=v2). Read the file COPYING that comes with GRASS GIS
for details.

:authors: Vaclav Petras
"""

from __future__ import print_function

import sys
import os
import argparse
import itertools
import subprocess
import locale

try:
    from itertools import izip as zip
except ImportError:  # will be 3.x series
    pass

if sys.version_info.major >= 3:
    unicode = str


def _get_encoding():
    encoding = locale.getdefaultlocale()[1]
    if not encoding:
        encoding = 'UTF-8'
    return encoding


def decode(bytes_, encoding=None):
    if isinstance(bytes_, bytes):
        return bytes_.decode(_get_encoding())
    else:
        return bytes_


def encode(string, encoding=None):
    if isinstance(string, unicode):
        return string.encode(_get_encoding())
    else:
        return string


def text_to_string(text):
    """Convert text to str. Useful when passing text into environments,
       in Python 2 it needs to be bytes on Windows, in Python 3 in needs unicode.
    """
    if sys.version[0] == '2':
        # Python 2
        return encode(text)
    else:
        # Python 3
        return decode(text)



def main():
    parser = argparse.ArgumentParser(
        description='Run tests with new')
    parser.add_argument('--location', '-l', required=True, action='append',
                        dest='locations', metavar='LOCATION',
                        help='Directories with reports')
    parser.add_argument('--location-type', '-t', action='append',
                        dest='location_types',
                    default=[], metavar='TYPE',
                    help='Add repeated values to a list',
                    )
    parser.add_argument('--grassbin', required=True,
                        help='Use file timestamp instead of date in test summary')
    # TODO: rename since every src can be used?
    parser.add_argument('--grasssrc', required=True,
                        help='GRASS GIS source code (to take tests from)')
    parser.add_argument('--grassdata', required=True,
                        help='GRASS GIS data base (GISDBASE)')
    parser.add_argument('--create-main-report',
                        help='Create also main report for all tests',
                        action="store_true", default=False, dest='main_report')

    args = parser.parse_args()
    gisdb = args.grassdata
    locations = args.locations
    locations_types = args.location_types

    # TODO: if locations empty or just one we can suppose the same all the time
    if len(locations) != len(locations_types):
        print("ERROR: Number of locations and their tags must be the same", file=sys.stderr)
        return 1
    

    main_report = args.main_report
    grasssrc = args.grasssrc  # TODO: can be guessed from dist    
    # TODO: create directory according to date and revision and create reports there

    # some predefined variables, name of the GRASS launch script + location/mapset
    #grass7bin = 'C:\Program Files (x86)\GRASS GIS 7.2.svn\grass77svn.bat'
    grass7bin = args.grassbin  # TODO: can be used if pressent

    ########### SOFTWARE
    # query GRASS 7 itself for its GISBASE
    # we assume that GRASS GIS' start script is available and in the PATH
    # the shell=True is here because of MS Windows? (code taken from wiki)
    startcmd = grass7bin + ' --config path'
    p = subprocess.Popen(startcmd, shell=True, 
                         stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    out, err = p.communicate()
    if p.returncode != 0:
        print("ERROR: Cannot find GRASS GIS 7 start script (%s):\n%s" % (startcmd, err), file=sys.stderr)
        return 1
    gisbase = decode(out.strip())

    # set GISBASE environment variable
    os.environ['GISBASE'] = text_to_string(gisbase)
    # define GRASS Python environment
    grass_python_dir = os.path.join(gisbase, "etc", "python")
    sys.path.append(grass_python_dir)

    ########### DATA
    # define GRASS DATABASE
    
    # Set GISDBASE environment variable
    os.environ['GISDBASE'] = text_to_string(gisdb)

    # import GRASS Python package for initialization
    import grass.script.setup as gsetup

    # launch session
    # we need some location and mapset here
    # TODO: can init work without it or is there some demo location in dist?
    location = locations[0].split(':')[0]
    mapset = 'PERMANENT'
    gsetup.init(gisbase, gisdb, location, mapset)

    reports = []
    for location, location_type in zip(locations, locations_types):
        # here it is quite a good place to parallelize
        # including also type to make it unique and preserve it for sure
        report = 'report_for_' + location + '_' + location_type
        absreport = os.path.abspath(report)
        p = subprocess.Popen([sys.executable, '-tt',
                              '-m', 'grass.gunittest.main',
                              '--grassdata', gisdb, '--location', location,
                              '--location-type', location_type,
                              '--output', absreport],
                              cwd=grasssrc)
        returncode = p.wait()
        reports.append(report)

    if main_report:
        # TODO: solve the path to source code (work now only for grass source code)
        arguments = [sys.executable, grasssrc + '/lib/python/guittest/' + 'multireport.py', '--timestapms']
        arguments.extend(reports)
        p = subprocess.Popen(arguments)
        returncode = p.wait()
        if returncode != 0:
            print("ERROR: Creation of main report failed.", file=sys.stderr)
            return 1

    return 0

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