/*
 * 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.CellSignalStrength;
import android.telephony.ModemActivityInfo;

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, CellSignalStrength.getNumSignalStrengthLevels()));
    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[CellSignalStrength.getNumSignalStrengthLevels()];
    Arrays.fill(mTimeInRxSignalStrengthLevelMs, 0);
    mTxTimeMs = new long[ModemActivityInfo.TX_POWER_LEVELS];
    Arrays.fill(mTxTimeMs, 0);
    mMonitoredRailChargeConsumedMaMs = 0;
    return;
  }
}
