#
# Copyright (C) 2016 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import re
import logging

from vts.utils.python.os import path_utils

from vts.testcases.kernel.ltp import ltp_enums
from vts.testcases.kernel.ltp import ltp_configs


class TestCase(object):
    """Stores name, path, and param information for each test case.

    All class initiation inputs are assumed to be already validated by
    test case parser.

    Attributes:
        testsuite: string, name of testsuite to which the testcase belongs
        testname: string, name of the test case
        command: string, the command to run the test case
        _args: list of string, test case command line arguments
        requirement_state: RequirementState, enum representing requirement
                            check results
        note: string, a place to store additional note for the test case
              such as what environment requirement did not satisfy.
        is_staging: bool, whether test case is a staging test
        is_filtered: bool, whether test case is excluded by filter
    """

    def __init__(self, testsuite, testname, command):
        self.testsuite = testsuite
        self.testname = testname
        self._command = command
        self.requirement_state = ltp_enums.RequirementState.UNCHECKED
        self.note = ""
        self.is_staging = False
        self.is_filtered = False

    @property
    def note(self):
        """Get the note"""
        return self._note

    @note.setter
    def note(self, note):
        """Set the note"""
        self._note = note

    @property
    def requirement_state(self):
        """Get the requirement state"""
        return self._requirement_state

    @requirement_state.setter
    def requirement_state(self, requirement_state):
        """Set the requirement state"""
        self._requirement_state = requirement_state

    @property
    def testsuite(self):
        """Get the test suite's name."""
        return self._testsuite

    @testsuite.setter
    def testsuite(self, testsuite):
        """Set the test suite's name."""
        self._testsuite = testsuite

    @property
    def testname(self):
        """Get the test case's name."""
        return self._testname

    @testname.setter
    def testname(self, testname):
        """Set the test case's name."""
        self._testname = testname

    def InternalAddLtpPathToCommand(self, command):
        """Internal function to change binary in commands to their full path"""
        tokens = command.strip().split()

        # If not ltp executables:
        if (tokens[0] in ltp_configs.INTERNAL_BINS or
                tokens[0] in ltp_configs.INTERNAL_SHELL_COMMANDS or
                tokens[0].find('=') > 0):
            return command
        else:  # Is Ltp executable
            tokens[0] = path_utils.JoinTargetPath(ltp_configs.LTPBINPATH,
                                                  tokens[0])
            return ' '.join(tokens)

    def GetCommand(self):
        """Get test case's command.

        Get the test case's command where ltp test binary names have been
        replaced with their full paths
        """
        return '&&'.join((self.InternalAddLtpPathToCommand(command)
                          for command in self._command.split('&&')))

    def InternalGetExecutableNames(self):
        """Get a generator of all required executable file names"""
        executables = (command.strip().split()[0]
                       for command in self._command.split('&&'))

        # In some test definitions there were command starting with
        # > TDsrc='mktemp ...'. We use regex to remove quotes
        pattern = re.compile('[\'|\"]')
        return (pattern.sub('', executable.split('=')[1])
                if executable.find('=') > 0 else executable
                for executable in executables)

    def GetRequiredExecutablePaths(self, ltp_bin_path=ltp_configs.LTPBINPATH):
        """Get required executables' paths.

        Returns:
            A list of all executables' paths that will be needed
            by its command. For LTP's executables, absolute path will be
            returned. For binaries in system's PATH, only the name will be
            returned.
        """
        return [path_utils.JoinTargetPath(ltp_bin_path, executable)
                if executable not in ltp_configs.INTERNAL_BINS else executable
                for executable in self.InternalGetExecutableNames()
                if executable not in ltp_configs.INTERNAL_SHELL_COMMANDS]

    @property
    def fullname(self):
        """Return full test name in <testsuite-testname> format"""
        return "%s.%s" % (self.testsuite, self.testname)

    def __str__(self):
        return self.fullname

    @property
    def is_staging(self):
        '''Whether this test is a staging test.'''
        return self._is_staging

    @is_staging.setter
    def is_staging(self, is_staging):
        '''Set whether this test is a staging test.'''
        self._is_staging = is_staging

    @property
    def is_filtered(self):
        '''Whether this test has been filtered out.'''
        return self._is_filtered

    @is_filtered.setter
    def is_filtered(self, is_filtered):
        '''Set whether this test has been filtered out.'''
        self._is_filtered = is_filtered
