#!/usr/bin/env python
#
# Copyright (C) 2017 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 os
import parse
import sys

from abc import ABCMeta
from abc import abstractmethod
from ply import lex
from ply import yacc
from vts.utils.python.file import target_file_utils


def repeat_rule(to_repeat, zero_ok=False):
    '''
    From a given rule, generates a rule that allows consecutive items
    of that rule. Instances are collected in a list.
    '''

    def p_multiple(self, p):
        if len(p) == 2 and zero_ok:
            p[0] = []
        elif len(p) == 2:
            p[0] = [p[1]]
        else:
            p[0] = p[1] + [p[2]]

    func = p_multiple
    format_tuple = (to_repeat, to_repeat, to_repeat, 'empty'
                    if zero_ok else to_repeat)
    func.__doc__ = '%ss : %ss %s \n| %s' % format_tuple
    return func


def literal_token(tok):
    '''
    A compact function to specify literal string tokens when.
    they need to take precedence over a generic string,
    Among these tokens precedence is decided in alphabetic order.
    '''

    def t_token(self, t):
        return t

    func = t_token
    func.__doc__ = tok
    return func


class KernelProcFileTestBase(object):
    """
    An abstract test for the formatting of a procfs file. Individual
    files can inherit from this class.

    New parsing rules can be defined in the form of p_RULENAME, and
    similarly new tokens can be defined as t_TOKENNAME.

    Child class should also specify a `start` variable to give the starting rule.
    """

    __metaclass__ = ABCMeta

    def t_HEX_LITERAL(self, t):
        r'0x[a-f0-9]+'
        t.value = int(t.value, 0)
        return t

    def t_FLOAT(self, t):
        r'([0-9]+[.][0-9]*|[0-9]*[.][0-9]+)'
        t.value = float(t.value)
        return t

    def t_NUMBER(self, t):
        r'\d+'
        t.value = int(t.value)
        return t

    t_PATH = r'/[^\0]+'
    t_COLON = r':'
    t_EQUALS = r'='
    t_COMMA = r','
    t_PERIOD = r'\.'
    t_STRING = r'[a-zA-Z\(\)_0-9\-@]+'

    t_TAB = r'\t'
    t_SPACE = r'[ ]'

    def t_DASH(self, t):
        r'\-'
        return t

    def t_NEWLINE(self, t):
        r'\n'
        t.lexer.lineno += len(t.value)
        return t

    t_ignore = ''

    def t_error(self, t):
        raise SyntaxError("Illegal character '%s' in line %d '%s'" % \
                (t.value[0], t.lexer.lineno, t.value.split()[0]))

    p_SPACEs = repeat_rule('SPACE', zero_ok=True)

    def p_error(self, p):
        raise SyntaxError("Parsing error at token %s in line %d" %
                          (p, p.lexer.lineno))

    def p_empty(self, p):
        'empty :'
        pass

    def __init__(self):
        self.tokens = [
            t_name[2:] for t_name in dir(self)
            if len(t_name) > 2 and t_name[:2] == 't_'
        ]
        self.tokens.remove('error')
        self.tokens.remove('ignore')
        self.lexer = lex.lex(module=self)
        # (Change logger output stream if debugging)
        self.parser = yacc.yacc(module=self, write_tables=False, \
                errorlog=yacc.PlyLogger(sys.stderr)) #open(os.devnull, 'w')))

    def parse_line(self, rule, line, custom={}):
        """Parse a line of text with the parse library.

        Args:
            line: string, a line of text
            rule: string, a format rule. See parse documentation
            custom: dict, maps to custom type conversion functions

        Returns:
            list, information parsed from the line

        Raises:
            SyntaxError: if the line could not be parsed.
        """
        parsed = parse.parse(rule, line, custom)
        if parsed is None:
            raise SyntaxError("Failed to parse line %s according to rule %s" %
                              (line, rule))
        return list(parsed)

    def parse_contents(self, file_contents):
        """Using the internal parser, parse the contents.

        Args:
            file_contents: string, entire contents of a file

        Returns:
            list, a parsed representation of the file

        Raises:
            SyntaxError: if the file could not be parsed
        """
        return self.parser.parse(file_contents, lexer=self.lexer)

    @abstractmethod
    def get_path(self):
        """Returns the full path of this proc file (string)."""
        pass

    def prepare_test(self, shell, dut):
        """Performs any actions necessary before testing the proc file.

        Args:
            shell: shell object, for preparation that requires device access

        Returns:
            boolean, True if successful.
        """
        return True

    def file_optional(self, shell=None, dut=None):
        """Performs any actions necessary to return if file is allowed to be absent

        Args:
            shell: shell object, to run commands on the device side
            dut: AndroidDevice object to access functions and properties of that object

        Returns:
            boolean, True if file is allowed to be absent.
        """
        return False

    def result_correct(self, parse_result):
        """Returns: True if the parsed result meets the requirements (boolean)."""
        return True

    def test_format(self):
        """Returns:
            boolean, True if the file should be read and its format tested.
                     False if only the existence and permission should be tested.
        """
        return True

    def get_permission_checker(self):
        """Gets the function handle to use for validating file permissions.

        Return the function that will check if the permissions are correct.
        By default, return the IsReadOnly function from target_file_utils.

        Returns:
            function which takes one argument (the unix file permission bits
            in octal format) and returns True if the permissions are correct,
            False otherwise.
        """
        return target_file_utils.IsReadOnly
