/*
 * Copyright (C) 2016 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.
 */

#ifndef _STORAGED_H_
#define _STORAGED_H_

#include <semaphore.h>
#include <stdint.h>
#include <time.h>

#include <queue>
#include <string>
#include <unordered_map>
#include <vector>

#include <batteryservice/IBatteryPropertiesListener.h>
#include <utils/Mutex.h>

#include <android/hardware/health/2.0/IHealth.h>

#define FRIEND_TEST(test_case_name, test_name) \
friend class test_case_name##_##test_name##_Test

#define ARRAY_SIZE(x)   (sizeof(x) / sizeof((x)[0]))

#define IS_ALIGNED(x, align)   (!((x) & ((align) - 1)))
#define ROUND_UP(x, align)     (((x) + ((align) - 1)) & ~((align) - 1))

#define SECTOR_SIZE ( 512 )
#define SEC_TO_MSEC ( 1000 )
#define MSEC_TO_USEC ( 1000 )
#define USEC_TO_NSEC ( 1000 )
#define SEC_TO_USEC ( 1000000 )
#define HOUR_TO_SEC ( 3600 )
#define DAY_TO_SEC ( 3600 * 24 )
#define WEEK_TO_DAYS ( 7 )
#define YEAR_TO_WEEKS ( 52 )

#include "storaged_diskstats.h"
#include "storaged_info.h"
#include "storaged_uid_monitor.h"
#include "storaged.pb.h"
#include "uid_info.h"

using namespace std;
using namespace android;

// Periodic chores intervals in seconds
#define DEFAULT_PERIODIC_CHORES_INTERVAL_UNIT ( 60 )
#define DEFAULT_PERIODIC_CHORES_INTERVAL_DISK_STATS_PUBLISH ( 3600 )
#define DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO ( 3600 )
#define DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO_LIMIT ( 300 )
#define DEFAULT_PERIODIC_CHORES_INTERVAL_FLUSH_PROTO ( 3600 )

// UID IO threshold in bytes
#define DEFAULT_PERIODIC_CHORES_UID_IO_THRESHOLD ( 1024 * 1024 * 1024ULL )

struct storaged_config {
    int periodic_chores_interval_unit;
    int periodic_chores_interval_disk_stats_publish;
    int periodic_chores_interval_uid_io;
    int periodic_chores_interval_flush_proto;
    int event_time_check_usec;  // check how much cputime spent in event loop
};

class storaged_t : public android::hardware::health::V2_0::IHealthInfoCallback,
                   public android::hardware::hidl_death_recipient {
  private:
    time_t mTimer;
    storaged_config mConfig;
    unique_ptr<disk_stats_monitor> mDsm;
    uid_monitor mUidm;
    time_t mStarttime;
    sp<android::hardware::health::V2_0::IHealth> health;
    unique_ptr<storage_info_t> storage_info;
    static const uint32_t current_version;
    unordered_map<userid_t, bool> proto_loaded;
    void load_proto(userid_t user_id);
    char* prepare_proto(userid_t user_id, StoragedProto* proto);
    void flush_proto(userid_t user_id, StoragedProto* proto);
    void flush_proto_data(userid_t user_id, const char* data, ssize_t size);
    string proto_path(userid_t user_id) {
        return string("/data/misc_ce/") + to_string(user_id) +
               "/storaged/storaged.proto";
    }
    void init_health_service();

  public:
    storaged_t(void);
    void init(void);
    void event(void);
    void event_checked(void);
    void pause(void) {
        sleep(mConfig.periodic_chores_interval_unit);
    }

    time_t get_starttime(void) {
        return mStarttime;
    }

    unordered_map<uint32_t, uid_info> get_uids(void) {
        return mUidm.get_uid_io_stats();
    }

    vector<int> get_perf_history(void) {
        return storage_info->get_perf_history();
    }

    uint32_t get_recent_perf(void) { return storage_info->get_recent_perf(); }

    map<uint64_t, struct uid_records> get_uid_records(
            double hours, uint64_t threshold, bool force_report) {
        return mUidm.dump(hours, threshold, force_report);
    }

    void update_uid_io_interval(int interval) {
        if (interval >= DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO_LIMIT) {
            mConfig.periodic_chores_interval_uid_io = interval;
        }
    }

    void add_user_ce(userid_t user_id);
    void remove_user_ce(userid_t user_id);

    virtual ::android::hardware::Return<void> healthInfoChanged(
        const ::android::hardware::health::V2_0::HealthInfo& info);
    void serviceDied(uint64_t cookie, const wp<::android::hidl::base::V1_0::IBase>& who);

    void report_storage_info();

    void flush_protos(unordered_map<int, StoragedProto>* protos);
};

// Eventlog tag
// The content must match the definition in EventLogTags.logtags
#define EVENTLOGTAG_DISKSTATS ( 2732 )
#define EVENTLOGTAG_EMMCINFO ( 2733 )
#define EVENTLOGTAG_UID_IO_ALERT ( 2734 )

#endif /* _STORAGED_H_ */
