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
13
14import hdf_utils
15
16
17class ConfigItem(object):
18    def __init__(self, index, line):
19        self.index = index
20        self.line = line
21
22
23class HdfDotConfigFile(object):
24    def __init__(self, dot_config_path):
25        self.file_path = dot_config_path
26        if os.path.exists(dot_config_path):
27            self.lines = hdf_utils.read_file_lines(dot_config_path)
28            self.dot_config_exist = True
29        else:
30            self.lines = []
31            self.dot_config_exist = False
32        self.cache = {}
33        self.hdf_item = 'LOSCFG_DRIVERS_HDF'
34        self.prefix = 'LOSCFG_'
35
36    def save(self):
37        if not self.dot_config_exist:
38            return
39        with open(self.file_path, 'r+', newline='\n') as file_read:
40            file_read.truncate()
41            file_read.write(''.join(self.lines))
42
43    def _update_cache(self, item, index, line):
44        self.cache[item] = ConfigItem(index, line)
45
46    def _find(self, item):
47        if item in self.cache:
48            index = self.cache.get(item).index
49            line = self.cache.get(item).line
50            return index, line
51        for index, line in enumerate(self.lines):
52            item_pattern = r'%s\s*(=|is)' % item
53            if re.search(item_pattern, line):
54                line_ = line.strip()
55                self._update_cache(item, index, line_)
56                return index, line_
57        return 0, ''
58
59    @staticmethod
60    def _is_line_enabled(line):
61        if line.strip().startswith('#'):
62            return False
63        return True
64
65    def _enable(self, item):
66        if not item:
67            return
68        new_line = '%s=y\n' % item
69        index, line = self._find(item)
70        if line:
71            if self._is_line_enabled(line):
72                return
73            self.lines[index] = new_line
74            self._update_cache(item, index, new_line)
75            return
76        else:
77            count = len(self.lines)
78            self.lines.append(new_line)
79            self._update_cache(item, count, new_line)
80
81    def _disable(self, item):
82        if not item:
83            return
84        new_line = '# %s is not set\n' % item
85        index, line = self._find(item)
86        if not line:
87            return
88        if not self._is_line_enabled(line):
89            return
90        self.lines[index] = new_line
91        self._update_cache(item, index, new_line)
92
93    def _is_enabled(self, item):
94        if not item:
95            return False
96        index, line = self._find(item)
97        if not line:
98            return False
99        return self._is_line_enabled(line)
100
101    def _add_prefix(self, item):
102        if not item.startswith(self.prefix):
103            item = '%s%s' % (self.prefix, item)
104        return item
105
106    def is_enabled(self, item, depends_on_item):
107        if item:
108            item = self._add_prefix(item)
109        if depends_on_item:
110            depends_on_item = self._add_prefix(depends_on_item)
111        if depends_on_item:
112            if not self._is_enabled(depends_on_item):
113                return False
114        return self._is_enabled(item)
115
116    def enable(self, item, depends_on_item):
117        if item:
118            item = self._add_prefix(item)
119        if depends_on_item:
120            depends_on_item = self._add_prefix(depends_on_item)
121        self._enable(self.hdf_item)
122        self._enable(depends_on_item)
123        self._enable(item)
124
125    def disable(self, item):
126        if item:
127            item = self._add_prefix(item)
128        self._disable(item)
129
130    def add_dot_config(self):
131        hdf_utils.get_dot_configs_path()
132