/*
* Copyright (C) 2012 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 com.fairphone.hiccup;
import android.util.Log;



import android.os.Binder;
import android.os.IBinder;
import android.os.IInterface;
import android.os.Parcel;
import android.os.RemoteException;
import com.fairphone.hiccup.LogFile;
import java.io.FileDescriptor;
import java.util.List;
import java.util.ArrayList;
import android.os.ParcelFileDescriptor;
/**
 * @hide
 */
public interface IHiccupdService extends IInterface {
  public static abstract class Stub extends Binder implements IHiccupdService {
    private static class Proxy implements IHiccupdService {
      private final IBinder mRemote;

      Proxy(IBinder remote) {
        mRemote = remote;
      }

      public IBinder asBinder() {
        return mRemote;
      }

      public String getInterfaceDescriptor() {
        return DESCRIPTOR;
      }

      public List<LogFile> getLogs() throws RemoteException {
        Parcel _data = Parcel.obtain();
        Parcel _reply = Parcel.obtain();
        ArrayList<LogFile> logFiles = null;
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          mRemote.transact(Stub.TRANSACTION_get_logs, _data, _reply, 0);
          int nLogFiles = _reply.readInt();
          logFiles = new ArrayList<LogFile>(nLogFiles);
          for (int i = 0; i < nLogFiles ; i++ ) {
            String fileName = _reply.readString();
            if(fileName == null) {
              fileName="UNKNOWN_FILE";
            }
            ParcelFileDescriptor pfd = _reply.readFileDescriptor();
            FileDescriptor fileDescriptor = (pfd != null)?pfd.getFileDescriptor():null;

            logFiles.add(new LogFile(fileName, fileDescriptor));
          }
        } finally {
          _reply.recycle();
          _data.recycle();
        }
        return logFiles;
      }

      public List<LogFile> getLastKmsg() throws RemoteException {
        Parcel _data = Parcel.obtain();
        Parcel _reply = Parcel.obtain();
        ArrayList<LogFile> logFiles = null;
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          mRemote.transact(Stub.TRANSACTION_get_last_kmesg, _data, _reply, 0);
          int nLogFiles = _reply.readInt();
          logFiles = new ArrayList<LogFile>(nLogFiles);
          for (int i = 0; i < nLogFiles ; i++ ) {
            String fileName = _reply.readString();
            if(fileName == null) {
              fileName="UNKNOWN_FILE";
            }
            ParcelFileDescriptor pfd = _reply.readFileDescriptor();
            FileDescriptor fileDescriptor = (pfd != null)?pfd.getFileDescriptor():null;
            logFiles.add(new LogFile(fileName, fileDescriptor));
          }
        } finally {
          _reply.recycle();
          _data.recycle();
        }
        return logFiles;
      }

      public void cleanLogs() throws RemoteException {
        Parcel _data = Parcel.obtain();
        Parcel _reply = Parcel.obtain();
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          mRemote.transact(Stub.TRANSACTION_clean_logs, _data, _reply, 0);
        } finally {
          _reply.recycle();
          _data.recycle();
        }
      }

      public void startLogging() throws RemoteException {
        Parcel _data = Parcel.obtain();
        Parcel _reply = Parcel.obtain();
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          mRemote.transact(Stub.TRANSACTION_start_logging, _data, _reply, 0);
        } finally {
          _reply.recycle();
          _data.recycle();
        }
      }

      public void stopLogging() throws RemoteException {
        Parcel _data = Parcel.obtain();
        Parcel _reply = Parcel.obtain();
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          mRemote.transact(Stub.TRANSACTION_stop_logging, _data, _reply, 0);
        } finally {
          _reply.recycle();
          _data.recycle();
        }
      }

      public String getBootReason() throws RemoteException {
        Parcel _data = Parcel.obtain();
        Parcel _reply = Parcel.obtain();
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          mRemote.transact(Stub.TRANSACTION_get_bootreason, _data, _reply, 0);
          return _reply.readString();
        } finally {
          _reply.recycle();
          _data.recycle();
        }
      }

      public String getPowerOnReason() throws RemoteException {
        Parcel _data = Parcel.obtain();
        Parcel _reply = Parcel.obtain();
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          mRemote.transact(Stub.TRANSACTION_get_poweronreason, _data, _reply, 0);
          return _reply.readString();
        } finally {
          _reply.recycle();
          _data.recycle();
        }
      }

      public String getPowerOffReason() throws RemoteException {
        Parcel _data = Parcel.obtain();
        Parcel _reply = Parcel.obtain();
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          mRemote.transact(Stub.TRANSACTION_get_poweroffreason, _data, _reply, 0);
          return _reply.readString();
        } finally {
          _reply.recycle();
          _data.recycle();
        }
      }

      public int getApiVersion() throws RemoteException {
        Parcel _data = Parcel.obtain();
        Parcel _reply = Parcel.obtain();
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          mRemote.transact(Stub.TRANSACTION_get_api_version, _data, _reply, 0);
          return _reply.readInt();
        } finally {
          _reply.recycle();
          _data.recycle();
        }
      }
    }

    private static final String DESCRIPTOR = "com.fairphone.IHiccupd";

    static final int TRANSACTION_get_logs            = IBinder.FIRST_CALL_TRANSACTION + 0;
    static final int TRANSACTION_clean_logs          = IBinder.FIRST_CALL_TRANSACTION + 1;
    static final int TRANSACTION_start_logging       = IBinder.FIRST_CALL_TRANSACTION + 2;
    static final int TRANSACTION_stop_logging        = IBinder.FIRST_CALL_TRANSACTION + 3;
    static final int TRANSACTION_get_bootreason      = IBinder.FIRST_CALL_TRANSACTION + 4;
    static final int TRANSACTION_get_poweronreason   = IBinder.FIRST_CALL_TRANSACTION + 5;
    static final int TRANSACTION_get_poweroffreason  = IBinder.FIRST_CALL_TRANSACTION + 6;
    static final int TRANSACTION_get_last_kmesg      = IBinder.FIRST_CALL_TRANSACTION + 7;
    static final int TRANSACTION_get_api_version     = IBinder.FIRST_CALL_TRANSACTION + 8;

    /**
    * Cast an IBinder object into an IHiccupdService interface, generating
    * a proxy if needed.
    */
    public static IHiccupdService asInterface(IBinder obj) {
      if (obj == null) {
        return null;
      }
      IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
      if (iin != null && iin instanceof IHiccupdService) {
        return (IHiccupdService) iin;
      }
      return new IHiccupdService.Stub.Proxy(obj);
    }

    /** Construct the stub at attach it to the interface. */
    public Stub() {
      attachInterface(this, DESCRIPTOR);
    }

    public IBinder asBinder() {
      return this;
    }

    @Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
    throws RemoteException {
      switch (code) {
        case INTERFACE_TRANSACTION: {
          reply.writeString(DESCRIPTOR);
          return true;
        }
      }
      return super.onTransact(code, data, reply, flags);
    }
  }

  public List<LogFile> getLogs() throws RemoteException;
  public List<LogFile> getLastKmsg() throws RemoteException;
  public void cleanLogs() throws RemoteException;
  public void startLogging() throws RemoteException;
  public void stopLogging() throws RemoteException;
  public String getBootReason() throws RemoteException;
  public String getPowerOnReason() throws RemoteException;
  public String getPowerOffReason() throws RemoteException;
  public int getApiVersion() throws RemoteException;

}
