/*
 * 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 <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_ */
