/*
 * 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.util;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Build;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.SystemClock;
import android.support.test.InstrumentationRegistry;

import java.io.Closeable;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

final class RemoteIntArray implements ServiceConnection, Closeable {
    private static final long BIND_REMOTE_SERVICE_TIMEOUT =
            ("eng".equals(Build.TYPE)) ? 120000 : 10000;

    private final Object mLock = new Object();

    private final Intent mIntent = new Intent();

    private android.util.IRemoteMemoryIntArray mRemoteInstance;

    public RemoteIntArray(int size) throws IOException, TimeoutException {
        mIntent.setComponent(new ComponentName(InstrumentationRegistry.getContext(),
                RemoteMemoryIntArrayService.class));
        synchronized (mLock) {
            if (mRemoteInstance == null) {
                bindLocked();
            }
            try {
                mRemoteInstance.create(size);
            } catch (RemoteException e) {
                throw new IOException(e);
            }
        }
    }

    public MemoryIntArray peekInstance() {
        try {
            return mRemoteInstance.peekInstance();
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    }

    public boolean isWritable() {
        try {
            return mRemoteInstance.isWritable();
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    }

    public int get(int index) throws IOException {
        try {
            return mRemoteInstance.get(index);
        } catch (RemoteException e) {
            throw new IOException(e);
        }
    }

    public void set(int index, int value) throws IOException {
        try {
            mRemoteInstance.set(index, value);
        } catch (RemoteException e) {
            throw new IOException(e);
        }
    }

    public int size() throws IOException {
        try {
            return mRemoteInstance.size();
        } catch (RemoteException e) {
            throw new IOException(e);
        }
    }

    public void close() {
        try {
            mRemoteInstance.close();
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    }

    public boolean isClosed() {
        try {
            return mRemoteInstance.isClosed();
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    }

    private void bindLocked() throws TimeoutException {
        if (mRemoteInstance != null) {
            return;
        }

        InstrumentationRegistry.getContext().bindService(mIntent, this, Context.BIND_AUTO_CREATE);

        final long startMillis = SystemClock.uptimeMillis();
        while (true) {
            if (mRemoteInstance != null) {
                break;
            }
            final long elapsedMillis = SystemClock.uptimeMillis() - startMillis;
            final long remainingMillis = BIND_REMOTE_SERVICE_TIMEOUT - elapsedMillis;
            if (remainingMillis <= 0) {
                throw new TimeoutException("Cannot get spooler!");
            }
            try {
                mLock.wait(remainingMillis);
            } catch (InterruptedException ie) {
                    /* ignore */
            }
        }

        mLock.notifyAll();
    }

    public void destroy() {
        synchronized (mLock) {
            if (mRemoteInstance == null) {
                return;
            }
            mRemoteInstance = null;
            InstrumentationRegistry.getContext().unbindService(this);
        }
    }

    public void accessLastElementInRemoteProcess(MemoryIntArray array) {
        try {
            mRemoteInstance.accessLastElementInRemoteProcess(array);
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        synchronized (mLock) {
            mRemoteInstance = android.util.IRemoteMemoryIntArray.Stub.asInterface(service);
            mLock.notifyAll();
        }
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        synchronized (mLock) {
            mRemoteInstance = null;
        }
    }
}