/*
 * 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 _RESOLVER_STATS_H_
#define _RESOLVER_STATS_H_

#include <time.h>

namespace android {
namespace net {

struct ResolverStats {
    // Offsets into the per-server resolver stats as encoded in vector<int32_t> stats of
    // getResolverInfo() of Netd's binder interface. The stats are based on data reported by
    // android_net_res_stats_get_info_for_net(), the usability is calculated by applying
    // android_net_res_stats_get_usable_servers() to this data.
    enum ResolverStatsOffsets {
        STATS_SUCCESSES = 0,    // # successes counted for this server
        STATS_ERRORS,           // # errors
        STATS_TIMEOUTS,         // # timeouts
        STATS_INTERNAL_ERRORS,  // # internal errors
        STATS_RTT_AVG,          // average round-trip-time
        STATS_LAST_SAMPLE_TIME, // time in s when the last sample was recorded
        STATS_USABLE,           // whether the server is considered usable
        STATS_COUNT             // total count of integers in the per-server data
    };

    int successes {-1};
    int errors {-1};
    int timeouts {-1};
    int internal_errors {-1};
    int rtt_avg {-1};
    time_t last_sample_time {0};
    bool usable {false};

    // Serialize the resolver stats to the end of |out|.
    void encode(std::vector<int32_t>* out) const;

    // Read the serialized resolverstats starting at |in[ofs]|.
    ssize_t decode(const std::vector<int32_t>& in, ssize_t ofs);

    // Serialize the contents of |stats| and append them to the end of |out|. Multiple arrays
    // can be written to the same output vector in sequence, however, the corresponding call
    // to decodeAll() will return the combined contents in one vector.
    static void encodeAll(const std::vector<ResolverStats>& stats, std::vector<int32_t>* out);

    // Decodes the serialized ResolverStats from |in| and appends them to stats.
    static bool decodeAll(const std::vector<int32_t>& in, std::vector<ResolverStats>* stats);
};


inline void ResolverStats::encode(std::vector<int32_t>* out) const {
    size_t ofs = out->size();
    out->resize(ofs + STATS_COUNT);
    int32_t* cur = &(*out)[ofs];
    cur[STATS_SUCCESSES] = successes;
    cur[STATS_ERRORS] = errors;
    cur[STATS_TIMEOUTS] = timeouts;
    cur[STATS_INTERNAL_ERRORS] = internal_errors;
    cur[STATS_RTT_AVG] = rtt_avg;
    cur[STATS_LAST_SAMPLE_TIME] = last_sample_time;
    cur[STATS_USABLE] = usable;
}

    // Read the serialized resolverstats starting at |in[ofs]|.
inline ssize_t ResolverStats::decode(const std::vector<int32_t>& in, ssize_t ofs) {
    if (ofs < 0 || static_cast<size_t>(ofs) + STATS_COUNT > in.size()) {
        return -1;
    }
    const int32_t* cur = &in[ofs];
    successes = cur[STATS_SUCCESSES];
    errors = cur[STATS_ERRORS];
    timeouts = cur[STATS_TIMEOUTS];
    internal_errors = cur[STATS_INTERNAL_ERRORS];
    rtt_avg = cur[STATS_RTT_AVG];
    last_sample_time = cur[STATS_LAST_SAMPLE_TIME];
    usable = cur[STATS_USABLE];
    return ofs + STATS_COUNT;
}

inline void ResolverStats::encodeAll(const std::vector<ResolverStats>& stats,
        std::vector<int32_t>* out) {
    for (const auto& s : stats) {
        s.encode(out);
    }
}

// TODO: Replace with a better representation, e.g. a Parcelable.
inline bool ResolverStats::decodeAll(const std::vector<int32_t>& in,
        std::vector<ResolverStats>* stats) {
    ssize_t size = in.size();
    if (size % STATS_COUNT) {
        return false;
    }
    stats->resize(size / STATS_COUNT);
    ssize_t ofs = 0;
    for (auto& s : *stats) {
        ofs = s.decode(in, ofs);
        if (ofs < 0) {
            return false;
        }
    }
    return true;
}

}  // namespace net
}  // namespace android

#endif /* _RESOLVER_STATS_H_ */
