1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4# Copyright (c) 2020-2021 Huawei Device Co., Ltd.
5#
6# HDF is dual licensed: you can use it either under the terms of
7# the GPL, or the BSD license, at your option.
8# See the LICENSE file in the root of this repository for complete details.
9
10
11import os
12import re
13from string import Template
14
15import hdf_utils
16from hdf_tool_exception import HdfToolException
17from hdf_tool_settings import HdfToolSettings
18from .hdf_liteos_scann import HdfLiteScan
19from .hdf_command_error_code import CommandErrorCode
20
21
22class EnableOperation(object):
23    def __init__(self, root, vendor, board, model):
24        self.root = root
25        self.vendor = vendor
26        self.board = board
27        self.model = model
28        if self.board.endswith("linux") or self.board.endswith("Hi3516DV300"):
29            pass
30        else:
31            temp_liteos_model_name = HdfLiteScan(
32                self.root, self.vendor, self.board).scan_build()
33            self.liteos_model_name = list(map(lambda x: x.strip(",").strip('"'),
34                                              temp_liteos_model_name))
35
36        self.makefile_path = hdf_utils.get_vendor_makefile_path(
37            root, kernel="linux")
38        if not os.path.exists(self.makefile_path):
39            raise HdfToolException(
40                'Makefile: %s not exist' % self.makefile_path,
41                CommandErrorCode.TARGET_NOT_EXIST)
42
43        self.contents_makefile = hdf_utils.read_file_lines(self.makefile_path)
44        self.re_temp2 = r'model/[a-z 0-9 _ ]+'
45        self.re_temp = r"^group"
46
47    def scan_makefile(self):
48        model_list = []
49        for i in self.contents_makefile:
50            result = re.search(self.re_temp2, i)
51            if result:
52                model_name = result.group().split('/')[-1]
53                if model_name not in model_list:
54                    model_list.append(model_name)
55        return list(set(model_list))
56
57    def scan_build(self):
58        start_index = 0
59        end_index = 0
60        state = 0
61        for index, line in enumerate(self.contents_build):
62            if re.compile(self.re_temp).match(line):
63                start_index = index
64                state += 1
65            elif line.strip() == "{" and start_index > 0:
66                state += 1
67            elif line.strip() == "}" and start_index > 0:
68                state -= 1
69                if state == 0:
70                    end_index = index + 1
71
72        model_list = []
73        for i in self.contents[start_index: end_index]:
74            model_name = re.compile(self.re_temp2).match(i.strip())
75            if model_name:
76                model_list.append(model_name.group().split('/')[-1])
77        return list(set(model_list))
78
79    def disable_model_liteos(self):
80        dot_file_list = hdf_utils.get_dot_configs_path(
81            self.root, self.vendor, self.board)
82        old_template_string = \
83            "LOSCFG_DRIVERS_HDF_${module_upper_case}=y"
84        new_template_string = \
85            "LOSCFG_DRIVERS_HDF_${module_upper_case} is not set\n"
86        return self.enable_disable_same_code(
87            new_template_string, old_template_string, dot_file_list)
88
89    def enable_model_liteos(self):
90        dot_file_list = hdf_utils.get_dot_configs_path(
91            self.root, self.vendor, self.board)
92        new_template_string = \
93            "LOSCFG_DRIVERS_HDF_${module_upper_case}=y\n"
94        old_template_string = \
95            "LOSCFG_DRIVERS_HDF_${module_upper_case} is not set"
96        return self.enable_disable_same_code(
97            new_template_string, old_template_string, dot_file_list)
98
99    def enable_disable_same_code(self, new_template_string,
100                                 old_template_string, dot_file_list):
101        new_demo_config = Template(new_template_string).substitute(
102            {"module_upper_case": self.model.upper()})
103        old_demo_config = Template(old_template_string).substitute(
104            {"module_upper_case": self.model.upper()})
105
106        if self.model not in self.liteos_model_name:
107            return False
108        for dot_file in dot_file_list:
109            file_lines = hdf_utils.read_file_lines(dot_file)
110            for index, line in enumerate(file_lines):
111                if old_demo_config == line.strip():
112                    file_lines[index] = new_demo_config
113            hdf_utils.write_file_lines(dot_file, file_lines)
114        return True
115
116    def operation_enable(self):
117        if self.board.endswith("Hi3516DV300"):
118            try:
119                if self.enable_model_linux():
120                    return "success(linux) enable %s" % self.model
121                else:
122                    return "%s model_name is not linux_l2 type" % self.model
123            except Exception:
124                raise "failure(linux) enable %s" % self.model
125            finally:
126                pass
127
128        elif self.board.endswith("hispark_taurus_linux"):
129            try:
130                if self.enable_model_linux():
131                    return "success(linux) enable %s" % self.model
132                else:
133                    return "%s model_name is not linux type" % self.model
134            except Exception:
135                raise "failure(linux) enable %s" % self.model
136            finally:
137                pass
138
139        elif self.board.endswith("hispark_taurus"):
140            try:
141                if self.enable_model_liteos():
142                    return "success(liteos) enable %s" % self.model
143                else:
144                    return "%s model_name is not liteos type" % self.model
145            except Exception:
146                raise "failure(liteos) enable %s" % self.model
147            finally:
148                pass
149
150        else:
151            return "this board name : (%s) is not support" % self.board
152
153    def operation_disable(self):
154        if self.board.endswith("Hi3516DV300"):
155            try:
156                if self.disable_model_linux():
157                    return "success(linux) disable %s" % self.model
158                else:
159                    return "%s model_name is not linux_l2 type" % self.model
160            except Exception:
161                raise "failure(linux) disable %s" % self.model
162            finally:
163                pass
164
165        elif self.board.endswith("hispark_taurus_linux"):
166            try:
167                if self.disable_model_linux():
168                    return "success(linux) disable %s" % self.model
169                else:
170                    return "%s model_name is not linux type" % self.model
171            except Exception:
172                raise "failure(linux) disable %s" % self.model
173            finally:
174                pass
175
176        elif self.board.endswith("hispark_taurus"):
177            try:
178                if self.disable_model_liteos():
179                    return "success(liteos) disable %s" % self.model
180                else:
181                    return "%s model_name is not liteos type" % self.model
182            except Exception:
183                raise "failure(liteos) disable %s" % self.model
184            finally:
185                pass
186
187        else:
188            return "this board name : (%s) is not support " % self.board
189
190    def get_config_config(self, kernel):
191        return os.path.join(self.root, "kernel", kernel, "config")
192
193    def get_config_patch(self, kernel):
194        return os.path.join(self.root, "kernel", kernel, "patches")
195
196    def _get_file_patch(self, patch, endswitch, split_sign):
197        file_path = []
198        for roots, dirs, files in os.walk(patch):
199            if endswitch == "defconfig":
200                files_list = list(filter(
201                    lambda x: x.split(split_sign)[-1] == endswitch, files))
202            else:
203                files_list = list(filter(lambda x: x == endswitch, files))
204            for file_name in files_list:
205                file_path.append(os.path.join(roots, file_name))
206        return file_path
207
208    def _get_config_linux(self):
209        config_path = self.get_config_config(kernel="linux")
210        config_path_list = self._get_file_patch(
211            patch=config_path, endswitch="defconfig", split_sign="_")
212
213        patch_path = self.get_config_patch(kernel="linux")
214        patch_path_list = self._get_file_patch(
215            patch=patch_path, endswitch="hi3516dv300.patch", split_sign=".")
216        config_path_list.extend(patch_path_list)
217
218        return config_path_list
219
220    def _replace_operation(self, new_string, old_string, file_path):
221        new_demo_config = Template(new_string).substitute(
222            {"module_upper_case": self.model.upper()})
223        old_demo_config = Template(old_string).substitute(
224            {"module_upper_case": self.model.upper()})
225
226        with open(file_path, 'rb') as f_read:
227            file_lines = f_read.readlines()
228        for index, line in enumerate(file_lines):
229            if old_demo_config.encode('utf-8') == line.strip():
230                file_lines[index] = new_demo_config.encode('utf-8')
231        config_info = HdfToolSettings().get_file_config_info()
232        write_fd = os.open(file_path, config_info["flags"], config_info["modes"])
233        with os.fdopen(write_fd, "wb") as f_write:
234            f_write.writelines(file_lines)
235        return True
236
237    def disable_model_linux(self):
238        if self.model not in self.scan_makefile():
239            return False
240        file_path_list = self._get_config_linux()
241        for file_path in file_path_list:
242            if file_path.split("_")[-1] == "defconfig":
243                old_template_string = \
244                    "CONFIG_DRIVERS_HDF_${module_upper_case}=y"
245                new_template_string = \
246                    "CONFIG_DRIVERS_HDF_${module_upper_case} is not set\n"
247            else:
248                old_template_string = \
249                    "+CONFIG_DRIVERS_HDF_${module_upper_case}=y"
250                new_template_string = \
251                    "+CONFIG_DRIVERS_HDF_${module_upper_case} is not set\n"
252            self._replace_operation(new_string=new_template_string,
253                                    old_string=old_template_string,
254                                    file_path=file_path)
255        return True
256
257    def enable_model_linux(self):
258        if self.model not in self.scan_makefile():
259            return False
260        file_path_list = self._get_config_linux()
261        for file_path in file_path_list:
262            if file_path.split("_")[-1] == "defconfig":
263                new_template_string \
264                    = "CONFIG_DRIVERS_HDF_${module_upper_case}=y\n"
265                old_template_string \
266                    = "CONFIG_DRIVERS_HDF_${module_upper_case} is not set"
267            else:
268                new_template_string \
269                    = "+CONFIG_DRIVERS_HDF_${module_upper_case}=y\n"
270                old_template_string = \
271                    "+CONFIG_DRIVERS_HDF_${module_upper_case} is not set"
272            self._replace_operation(new_string=new_template_string,
273                                    old_string=old_template_string,
274                                    file_path=file_path)
275        return True
276