#    Copyright 2015 ARM Limited
#
# 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 re

from devlib.module import Module

class TripPoint(object):
    def __init__(self, zone, _id):
        self._id = _id
        self.zone = zone
        self.temp_node = 'trip_point_' + _id + '_temp'
        self.type_node = 'trip_point_' + _id + '_type'

    @property
    def target(self):
        return self.zone.target

    def get_temperature(self):
        """Returns the currently configured temperature of the trip point"""
        temp_file = self.target.path.join(self.zone.path, self.temp_node)
        return self.target.read_int(temp_file)

    def set_temperature(self, temperature):
        temp_file = self.target.path.join(self.zone.path, self.temp_node)
        self.target.write_value(temp_file, temperature)

    def get_type(self):
        """Returns the type of trip point"""
        type_file = self.target.path.join(self.zone.path, self.type_node)
        return self.target.read_value(type_file)

class ThermalZone(object):
    def __init__(self, target, root, _id):
        self.target = target
        self.name = 'thermal_zone' + _id
        self.path = target.path.join(root, self.name)
        self.trip_points = {}

        for entry in self.target.list_directory(self.path):
            re_match = re.match('^trip_point_([0-9]+)_temp', entry)
            if re_match is not None:
                self.add_trip_point(re_match.group(1))

    def add_trip_point(self, _id):
        self.trip_points[int(_id)] = TripPoint(self, _id)

    def is_enabled(self):
        """Returns a boolean representing the 'mode' of the thermal zone"""
        value = self.target.read_value(self.target.path.join(self.path, 'mode'))
        return value == 'enabled'

    def set_mode(self, enable):
        value = 'enabled' if enable else 'disabled'
        self.target.write_value(self.target.path.join(self.path, 'mode'), value)

    def get_temperature(self):
        """Returns the temperature of the thermal zone"""
        temp_file = self.target.path.join(self.path, 'temp')
        return self.target.read_int(temp_file)

class ThermalModule(Module):
    name = 'thermal'
    thermal_root = '/sys/class/thermal'

    @staticmethod
    def probe(target):

        if target.file_exists(ThermalModule.thermal_root):
            return True

    def __init__(self, target):
        super(ThermalModule, self).__init__(target)

        self.zones = {}
        self.cdevs = []

        for entry in target.list_directory(self.thermal_root):
            re_match = re.match('^(thermal_zone|cooling_device)([0-9]+)', entry)

            if re_match.group(1) == 'thermal_zone':
                self.add_thermal_zone(re_match.group(2))
            elif re_match.group(1) == 'cooling_device':
                # TODO
                pass

    def add_thermal_zone(self, _id):
        self.zones[int(_id)] = ThermalZone(self.target, self.thermal_root, _id)

    def disable_all_zones(self):
        """Disables all the thermal zones in the target"""
        for zone in self.zones:
            zone.set_mode('disabled')
