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 json
13import argparse
14
15import hdf_utils
16from hdf_tool_settings import HdfToolSettings
17from hdf_tool_exception import HdfToolException
18from .hdf_command_handler_base import HdfCommandHandlerBase
19from .hdf_command_error_code import CommandErrorCode
20from .hdf_dot_config_file import HdfDotConfigFile
21from .hdf_model_enable_operation import EnableOperation
22from .hdf_vendor_kconfig_file import HdfVendorKconfigFile
23from .hdf_vendor_mk_file import HdfVendorMkFile
24from .hdf_lite_mk_file import HdfLiteMkFile
25from .hdf_lite_kconfig_file import HdfLiteKconfigFile
26
27
28class ConfigItemsAction(argparse.Action):
29    def __call__(self, parser, namespace, values, option_string=None):
30        setattr(namespace, self.dest, " ".join(values))
31
32
33class HdfSetHandler(HdfCommandHandlerBase):
34    def __init__(self, args):
35        super(HdfSetHandler, self).__init__()
36        self.cmd = 'set'
37        self.handlers = {
38            'current_vendor': self._set_current_vendor_handler,
39            'current_board': self._set_current_board_handler,
40            'vendor_new_name': self._set_vendor_new_name_handler,
41            'drivers_state': self._set_drivers_state_handler,
42            'model_enable': self._enable_operation,
43            'model_disable': self._disable_operation,
44        }
45        self.parser.add_argument("--action_type",
46                                 help=' '.join(self.handlers.keys()),
47                                 required=True)
48        self.parser.add_argument("--root_dir", required=True)
49        self.parser.add_argument("--vendor_name")
50        self.parser.add_argument("--board_name")
51        self.parser.add_argument("--module_name")
52        self.parser.add_argument("--new_vendor_name")
53        self.parser.add_argument("--all_drivers", nargs='*',
54                                 action=ConfigItemsAction)
55        self.args = self.parser.parse_args(args)
56
57    def _set_current_vendor_handler(self):
58        self.check_arg_raise_if_not_exist("vendor_name")
59        root, vendor, _, _, _ = self.get_args()
60        HdfLiteMkFile(root).set_vendor(vendor)
61        HdfLiteKconfigFile(root).set_vendor(vendor)
62
63    def _set_current_board_handler(self):
64        return
65
66    def _set_vendor_new_name_handler(self):
67        self.check_arg_raise_if_not_exist("vendor_name")
68        self.check_arg_raise_if_not_exist("new_vendor_name")
69        root_dir = self.args.root_dir
70        old_name = self.args.vendor_name
71        new_name = self.args.new_vendor_name
72        src_vendor = hdf_utils.get_vendor_dir(root_dir, old_name)
73        if not os.path.exists(src_vendor):
74            raise HdfToolException('vendor: "%s" not exist' % old_name,
75                                   CommandErrorCode.TARGET_NOT_EXIST)
76        dst_vendor = hdf_utils.get_vendor_dir(root_dir, new_name)
77        if os.path.exists(dst_vendor):
78            raise HdfToolException('vendor: "%s" already exist' % new_name,
79                                   CommandErrorCode.TARGET_ALREADY_EXIST)
80        need_update_current_vendor = False
81        hdf_lite = HdfLiteMkFile(root_dir)
82        if hdf_lite.get_current_vendor() == old_name:
83            need_update_current_vendor = True
84        os.rename(src_vendor, dst_vendor)
85        if need_update_current_vendor:
86            hdf_lite.set_vendor(new_name)
87        HdfVendorKconfigFile(root_dir, new_name, kernel=None, path='').rename_vendor()
88        HdfVendorMkFile(root_dir, new_name).rename_vendor()
89
90    def _set_drivers_state_handler(self):
91        self.check_arg_raise_if_not_exist("all_drivers")
92        self.check_arg_raise_if_not_exist("board_name")
93        drivers = json.loads(self.args.all_drivers)
94        board_name = self.args.board_name.lower()
95        root = self.args.root_dir
96        dot_config_path = hdf_utils.get_liteos_a_dot_config_path(root)
97        dot_config = HdfDotConfigFile(dot_config_path)
98        orig_dot_configs = HdfToolSettings().get_dot_configs(board_name)
99        orig_dot_configs = \
100            [os.path.join(root, config) for config in orig_dot_configs]
101        orig_dot_configs = \
102            [HdfDotConfigFile(config) for config in orig_dot_configs]
103
104        def config_set(config):
105            if not config:
106                return
107            enabled = config.get('enabled', False)
108            config_item = config.get('config_item', '')
109            depends_on_item = config.get('depends_on_item', '')
110            if enabled:
111                dot_config.enable(config_item, depends_on_item)
112                for orig_dot_config in orig_dot_configs:
113                    orig_dot_config.enable(config_item, depends_on_item)
114            else:
115                dot_config.disable(config_item)
116                for orig_dot_config in orig_dot_configs:
117                    orig_dot_config.disable(config_item)
118
119        for module, module_state in drivers.items():
120            config_set(module_state.get('self', ''))
121            for drv_config in module_state.get('children', []):
122                config_set(drv_config)
123        dot_config.save()
124        for orig_dot_config_ in orig_dot_configs:
125            orig_dot_config_.save()
126
127    def _enable_operation(self):
128        self.check_arg_raise_if_not_exist("root_dir")
129        self.check_arg_raise_if_not_exist("vendor_name")
130        self.check_arg_raise_if_not_exist("board_name")
131        self.check_arg_raise_if_not_exist("module_name")
132        root, vendor, model, _, board, _, _ = self.get_args()
133        return EnableOperation(
134            root=root, vendor=vendor, board=board,
135            model=model).operation_enable()
136
137    def _disable_operation(self):
138        self.check_arg_raise_if_not_exist("root_dir")
139        self.check_arg_raise_if_not_exist("vendor_name")
140        self.check_arg_raise_if_not_exist("board_name")
141        self.check_arg_raise_if_not_exist("module_name")
142        root, vendor, model, _, board, _, _ = self.get_args()
143        return EnableOperation(
144            root=root, vendor=vendor, board=board,
145            model=model).operation_disable()