#!/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 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_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):
        """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 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 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 file_utils.IsReadOnly
