/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * 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.
 */

#pragma once

#include <aidl/android/hardware/thermal/IThermal.h>

#include <array>
#include <chrono>
#include <map>
#include <mutex>
#include <shared_mutex>
#include <string>
#include <string_view>
#include <thread>
#include <unordered_map>
#include <vector>

#include "utils/power_files.h"
#include "utils/powerhal_helper.h"
#include "utils/thermal_files.h"
#include "utils/thermal_info.h"
#include "utils/thermal_throttling.h"
#include "utils/thermal_watcher.h"

namespace aidl {
namespace android {
namespace hardware {
namespace thermal {
namespace implementation {

using ::android::sp;

using NotificationCallback = std::function<void(const Temperature &t)>;

// Get thermal_zone type
bool getThermalZoneTypeById(int tz_id, std::string *);

struct ThermalSample {
    float temp;
    boot_clock::time_point timestamp;
};

struct EmulSetting {
    float emul_temp;
    int emul_severity;
    bool pending_update;
};

struct SensorStatus {
    ThrottlingSeverity severity;
    ThrottlingSeverity prev_hot_severity;
    ThrottlingSeverity prev_cold_severity;
    ThrottlingSeverity prev_hint_severity;
    boot_clock::time_point last_update_time;
    ThermalSample thermal_cached;
    std::unique_ptr<EmulSetting> emul_setting;
};

class ThermalHelper {
  public:
    explicit ThermalHelper(const NotificationCallback &cb);
    ~ThermalHelper() = default;

    bool fillCurrentTemperatures(bool filterType, bool filterCallback, TemperatureType type,
                                 std::vector<Temperature> *temperatures);
    bool fillTemperatureThresholds(bool filterType, TemperatureType type,
                                   std::vector<TemperatureThreshold> *thresholds) const;
    bool fillCurrentCoolingDevices(bool filterType, CoolingType type,
                                   std::vector<CoolingDevice> *coolingdevices) const;
    bool emulTemp(std::string_view target_sensor, const float temp);
    bool emulSeverity(std::string_view target_sensor, const int severity);
    bool emulClear(std::string_view target_sensor);

    // Disallow copy and assign.
    ThermalHelper(const ThermalHelper &) = delete;
    void operator=(const ThermalHelper &) = delete;

    bool isInitializedOk() const { return is_initialized_; }

    // Read the temperature of a single sensor.
    bool readTemperature(std::string_view sensor_name, Temperature *out);
    bool readTemperature(
            std::string_view sensor_name, Temperature *out,
            std::pair<ThrottlingSeverity, ThrottlingSeverity> *throtting_status = nullptr,
            const bool force_sysfs = false);

    bool readTemperatureThreshold(std::string_view sensor_name, TemperatureThreshold *out) const;
    // Read the value of a single cooling device.
    bool readCoolingDevice(std::string_view cooling_device, CoolingDevice *out) const;
    // Get SensorInfo Map
    const std::unordered_map<std::string, SensorInfo> &GetSensorInfoMap() const {
        return sensor_info_map_;
    }
    // Get CdevInfo Map
    const std::unordered_map<std::string, CdevInfo> &GetCdevInfoMap() const {
        return cooling_device_info_map_;
    }
    // Get SensorStatus Map
    const std::unordered_map<std::string, SensorStatus> &GetSensorStatusMap() const {
        std::shared_lock<std::shared_mutex> _lock(sensor_status_map_mutex_);
        return sensor_status_map_;
    }
    // Get ThermalThrottling Map
    const std::unordered_map<std::string, ThermalThrottlingStatus> &GetThermalThrottlingStatusMap()
            const {
        return thermal_throttling_.GetThermalThrottlingStatusMap();
    }
    // Get PowerRailInfo Map
    const std::unordered_map<std::string, PowerRailInfo> &GetPowerRailInfoMap() const {
        return power_files_.GetPowerRailInfoMap();
    }

    // Get PowerStatus Map
    const std::unordered_map<std::string, PowerStatus> &GetPowerStatusMap() const {
        return power_files_.GetPowerStatusMap();
    }

    void sendPowerExtHint(const Temperature &t);
    bool isAidlPowerHalExist() { return power_hal_service_.isAidlPowerHalExist(); }
    bool isPowerHalConnected() { return power_hal_service_.isPowerHalConnected(); }
    bool isPowerHalExtConnected() { return power_hal_service_.isPowerHalExtConnected(); }

  private:
    bool initializeSensorMap(const std::unordered_map<std::string, std::string> &path_map);
    bool initializeCoolingDevices(const std::unordered_map<std::string, std::string> &path_map);
    bool isSubSensorValid(std::string_view sensor_data, const SensorFusionType sensor_fusion_type);
    void setMinTimeout(SensorInfo *sensor_info);
    void initializeTrip(const std::unordered_map<std::string, std::string> &path_map,
                        std::set<std::string> *monitored_sensors, bool thermal_genl_enabled);
    void clearAllThrottling();
    // For thermal_watcher_'s polling thread, return the sleep interval
    std::chrono::milliseconds thermalWatcherCallbackFunc(
            const std::set<std::string> &uevent_sensors);
    // Return hot and cold severity status as std::pair
    std::pair<ThrottlingSeverity, ThrottlingSeverity> getSeverityFromThresholds(
            const ThrottlingArray &hot_thresholds, const ThrottlingArray &cold_thresholds,
            const ThrottlingArray &hot_hysteresis, const ThrottlingArray &cold_hysteresis,
            ThrottlingSeverity prev_hot_severity, ThrottlingSeverity prev_cold_severity,
            float value) const;
    // Read sensor data according to the type
    bool readDataByType(std::string_view sensor_data, float *reading_value,
                        const SensorFusionType type, const bool force_no_cache,
                        std::map<std::string, float> *sensor_log_map);
    // Read temperature data according to thermal sensor's info
    bool readThermalSensor(std::string_view sensor_name, float *temp, const bool force_sysfs,
                           std::map<std::string, float> *sensor_log_map);
    bool connectToPowerHal();
    void updateSupportedPowerHints();
    void updateCoolingDevices(const std::vector<std::string> &cooling_devices_to_update);
    sp<ThermalWatcher> thermal_watcher_;
    PowerFiles power_files_;
    ThermalFiles thermal_sensors_;
    ThermalFiles cooling_devices_;
    ThermalThrottling thermal_throttling_;
    bool is_initialized_;
    const NotificationCallback cb_;
    std::unordered_map<std::string, CdevInfo> cooling_device_info_map_;
    std::unordered_map<std::string, SensorInfo> sensor_info_map_;
    std::unordered_map<std::string, std::unordered_map<ThrottlingSeverity, ThrottlingSeverity>>
            supported_powerhint_map_;
    PowerHalService power_hal_service_;
    mutable std::shared_mutex sensor_status_map_mutex_;
    std::unordered_map<std::string, SensorStatus> sensor_status_map_;
};

}  // namespace implementation
}  // namespace thermal
}  // namespace hardware
}  // namespace android
}  // namespace aidl
