1#
2# Copyright (C) 2018 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the 'License');
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#      http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an 'AS IS' BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16
17import argparse
18import logging
19import re
20
21from host_controller import console_argument_parser
22
23# tmp_dir variable name.
24TMP_DIR_VAR ="{tmp_dir}"
25
26
27class BaseCommandProcessor(object):
28    '''Base class for command processors.
29
30    Attributes:
31        arg_parser: ConsoleArgumentParser object, argument parser.
32        arg_buffer: dict, stores last parsed argument, value pairs.
33        console: cmd.Cmd console object.
34        command: string, command name which this processor will handle.
35        command_detail: string, detailed explanation for the command.
36    '''
37
38    command = 'base'
39    command_detail = 'Command processor template'
40
41    def _SetUp(self, console):
42        '''Internal SetUp function that will call subclass' Setup function.
43
44        Args:
45            console: Console object.
46        '''
47        self.console = console
48        self.arg_buffer = {}
49        self.arg_parser = console_argument_parser.ConsoleArgumentParser(
50            self.command, self.command_detail)
51        self.SetUp()
52
53    def SetUp(self):
54        '''SetUp method for subclass to override.'''
55        pass
56
57    def _Run(self, arg_line):
58        '''Internal function that will call subclass' Run function.
59
60        Args:
61            arg_line: string, line of command arguments
62        '''
63        ret = self.Run(arg_line)
64        args = self.arg_parser.ParseLine(arg_line)
65        for arg_tuple in args._get_kwargs():
66            key = arg_tuple[0]
67            value = arg_tuple[1]
68            self.arg_buffer[key] = value
69
70        if ret is not None:
71            if ret == True:  # exit command executed.
72                return True
73            elif ret == False:
74                return False
75            else:
76                logging.warning("{} coommand returned {}".format(
77                    self.command, ret))
78
79    def Run(self, arg_line):
80        '''Run method to perform action when invoked from console.
81
82        Args:
83            arg_line: string, line of command
84        '''
85        pass
86
87    def _Help(self):
88        '''Internal function that will call subclass' Help function.'''
89        self.Help()
90
91    def Help(self):
92        '''Help method to print help informations.'''
93        if hasattr(self, 'arg_parser') and hasattr(self.console, '_out_file'):
94            self.arg_parser.print_help(self.console._out_file)
95
96    def _TearDown(self):
97        '''Internal function that will call subclass' TearDown function.'''
98        self.TearDown()
99
100    def TearDown(self):
101        '''TearDown tasks to be called when console is shutting down.'''
102        pass
103
104    def ReplaceVars(self, message_list):
105        """Replaces vars in a 'messsag_list' to their values."""
106        new_message_list = []
107        for message in message_list:
108            new_message = message
109
110            vars = re.findall(r"{device-image\[[^]]+\]}", message)
111            if vars:
112                for var in vars:
113                    var_name = var[len("{device-image")+1:-2]
114                    if var_name and var_name in self.console.device_image_info:
115                        new_message = new_message.replace(
116                                var, self.console.device_image_info[var_name])
117                    else:
118                        new_message = new_message.replace(var, "{undefined}")
119
120            vars = re.findall(r"{tools\[[^]]+\]}", message)
121            if vars:
122                for var in vars:
123                    var_name = var[len("{tools")+1:-2]
124                    if var_name and var_name in self.console.tools_info:
125                        new_message = new_message.replace(
126                            var, self.console.tools_info[var_name])
127                    else:
128                        new_message = new_message.replace(var, "{undefined}")
129
130            if TMP_DIR_VAR in new_message:
131                new_message = new_message.replace(
132                    TMP_DIR_VAR, self.console.tmpdir_default)
133
134            new_message_list.append(new_message)
135        return new_message_list
136