/*
 * 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.
 */
package android.os.connectivity;

import android.os.BatteryStats;
import android.os.Parcel;
import android.os.Parcelable;

import android.telephony.ModemActivityInfo;
import android.telephony.SignalStrength;

import java.util.Arrays;

/**
 * API for Cellular power stats
 *
 * @hide
 */
public final class CellularBatteryStats implements Parcelable {

  private long mLoggingDurationMs;
  private long mKernelActiveTimeMs;
  private long mNumPacketsTx;
  private long mNumBytesTx;
  private long mNumPacketsRx;
  private long mNumBytesRx;
  private long mSleepTimeMs;
  private long mIdleTimeMs;
  private long mRxTimeMs;
  private long mEnergyConsumedMaMs;
  private long[] mTimeInRatMs;
  private long[] mTimeInRxSignalStrengthLevelMs;
  private long[] mTxTimeMs;
  private long mMonitoredRailChargeConsumedMaMs;

  public static final @android.annotation.NonNull Parcelable.Creator<CellularBatteryStats> CREATOR = new
      Parcelable.Creator<CellularBatteryStats>() {
        public CellularBatteryStats createFromParcel(Parcel in) {
          return new CellularBatteryStats(in);
        }

        public CellularBatteryStats[] newArray(int size) {
          return new CellularBatteryStats[size];
        }
      };

  public CellularBatteryStats() {
    initialize();
  }

  public void writeToParcel(Parcel out, int flags) {
    out.writeLong(mLoggingDurationMs);
    out.writeLong(mKernelActiveTimeMs);
    out.writeLong(mNumPacketsTx);
    out.writeLong(mNumBytesTx);
    out.writeLong(mNumPacketsRx);
    out.writeLong(mNumBytesRx);
    out.writeLong(mSleepTimeMs);
    out.writeLong(mIdleTimeMs);
    out.writeLong(mRxTimeMs);
    out.writeLong(mEnergyConsumedMaMs);
    out.writeLongArray(mTimeInRatMs);
    out.writeLongArray(mTimeInRxSignalStrengthLevelMs);
    out.writeLongArray(mTxTimeMs);
    out.writeLong(mMonitoredRailChargeConsumedMaMs);
  }

  public void readFromParcel(Parcel in) {
    mLoggingDurationMs = in.readLong();
    mKernelActiveTimeMs = in.readLong();
    mNumPacketsTx = in.readLong();
    mNumBytesTx = in.readLong();
    mNumPacketsRx = in.readLong();
    mNumBytesRx = in.readLong();
    mSleepTimeMs = in.readLong();
    mIdleTimeMs = in.readLong();
    mRxTimeMs = in.readLong();
    mEnergyConsumedMaMs = in.readLong();
    in.readLongArray(mTimeInRatMs);
    in.readLongArray(mTimeInRxSignalStrengthLevelMs);
    in.readLongArray(mTxTimeMs);
    mMonitoredRailChargeConsumedMaMs = in.readLong();
  }

  public long getLoggingDurationMs() {
    return mLoggingDurationMs;
  }

  public long getKernelActiveTimeMs() {
    return mKernelActiveTimeMs;
  }

  public long getNumPacketsTx() {
    return mNumPacketsTx;
  }

  public long getNumBytesTx() {
    return mNumBytesTx;
  }

  public long getNumPacketsRx() {
    return mNumPacketsRx;
  }

  public long getNumBytesRx() {
    return mNumBytesRx;
  }

  public long getSleepTimeMs() {
    return mSleepTimeMs;
  }

  public long getIdleTimeMs() {
    return mIdleTimeMs;
  }

  public long getRxTimeMs() {
    return mRxTimeMs;
  }

  public long getEnergyConsumedMaMs() {
    return mEnergyConsumedMaMs;
  }

  public long[] getTimeInRatMs() {
    return mTimeInRatMs;
  }

  public long[] getTimeInRxSignalStrengthLevelMs() {
    return mTimeInRxSignalStrengthLevelMs;
  }

  public long[] getTxTimeMs() {
    return mTxTimeMs;
  }

  public long getMonitoredRailChargeConsumedMaMs() {
    return mMonitoredRailChargeConsumedMaMs;
  }

  public void setLoggingDurationMs(long t) {
    mLoggingDurationMs = t;
    return;
  }

  public void setKernelActiveTimeMs(long t) {
    mKernelActiveTimeMs = t;
    return;
  }

  public void setNumPacketsTx(long n) {
    mNumPacketsTx = n;
    return;
  }

  public void setNumBytesTx(long b) {
    mNumBytesTx = b;
    return;
  }

  public void setNumPacketsRx(long n) {
    mNumPacketsRx = n;
    return;
  }

  public void setNumBytesRx(long b) {
    mNumBytesRx = b;
    return;
  }

  public void setSleepTimeMs(long t) {
    mSleepTimeMs = t;
    return;
  }

  public void setIdleTimeMs(long t) {
    mIdleTimeMs = t;
    return;
  }

  public void setRxTimeMs(long t) {
    mRxTimeMs = t;
    return;
  }

  public void setEnergyConsumedMaMs(long e) {
    mEnergyConsumedMaMs = e;
    return;
  }

  public void setTimeInRatMs(long[] t) {
    mTimeInRatMs = Arrays.copyOfRange(t, 0,
        Math.min(t.length, BatteryStats.NUM_DATA_CONNECTION_TYPES));
    return;
  }

  public void setTimeInRxSignalStrengthLevelMs(long[] t) {
    mTimeInRxSignalStrengthLevelMs = Arrays.copyOfRange(t, 0,
        Math.min(t.length, SignalStrength.NUM_SIGNAL_STRENGTH_BINS));
    return;
  }

  public void setTxTimeMs(long[] t) {
    mTxTimeMs = Arrays.copyOfRange(t, 0, Math.min(t.length, ModemActivityInfo.TX_POWER_LEVELS));
    return;
  }

  public void setMonitoredRailChargeConsumedMaMs(long monitoredRailEnergyConsumedMaMs) {
    mMonitoredRailChargeConsumedMaMs = monitoredRailEnergyConsumedMaMs;
    return;
  }

  public int describeContents() {
    return 0;
  }

  private CellularBatteryStats(Parcel in) {
    initialize();
    readFromParcel(in);
  }

  private void initialize() {
    mLoggingDurationMs = 0;
    mKernelActiveTimeMs = 0;
    mNumPacketsTx = 0;
    mNumBytesTx = 0;
    mNumPacketsRx = 0;
    mNumBytesRx = 0;
    mSleepTimeMs = 0;
    mIdleTimeMs = 0;
    mRxTimeMs = 0;
    mEnergyConsumedMaMs = 0;
    mTimeInRatMs = new long[BatteryStats.NUM_DATA_CONNECTION_TYPES];
    Arrays.fill(mTimeInRatMs, 0);
    mTimeInRxSignalStrengthLevelMs = new long[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
    Arrays.fill(mTimeInRxSignalStrengthLevelMs, 0);
    mTxTimeMs = new long[ModemActivityInfo.TX_POWER_LEVELS];
    Arrays.fill(mTxTimeMs, 0);
    mMonitoredRailChargeConsumedMaMs = 0;
    return;
  }
}