/*
 * Copyright (C) 2017 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.car.vms;


import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;

import com.android.internal.annotations.GuardedBy;

import java.lang.ref.WeakReference;

/**
 * Services that need VMS publisher services need to inherit from this class and also need to be
 * declared in the array vmsPublisherClients located in
 * packages/services/Car/service/res/values/config.xml (most likely, this file will be in an overlay
 * of the target product.
 *
 * The {@link com.android.car.VmsPublisherService} will start this service. The callback
 * {@link #onVmsPublisherServiceReady()} notifies when VMS publisher services can be used, and the
 * publisher can request a publisher ID in order to start publishing.
 *
 * SystemApi candidate.
 *
 * @hide
 */
@SystemApi
public abstract class VmsPublisherClientService extends Service {
    private static final boolean DBG = true;
    private static final String TAG = "VmsPublisherClient";

    private final Object mLock = new Object();

    private Handler mHandler = new VmsEventHandler(this);
    private final VmsPublisherClientBinder mVmsPublisherClient = new VmsPublisherClientBinder(this);
    private volatile IVmsPublisherService mVmsPublisherService = null;
    @GuardedBy("mLock")
    private IBinder mToken = null;

    @Override
    public IBinder onBind(Intent intent) {
        if (DBG) {
            Log.d(TAG, "onBind, intent: " + intent);
        }
        return mVmsPublisherClient.asBinder();
    }

    @Override
    public boolean onUnbind(Intent intent) {
        if (DBG) {
            Log.d(TAG, "onUnbind, intent: " + intent);
        }
        stopSelf();
        return super.onUnbind(intent);
    }

    private void setToken(IBinder token) {
        synchronized (mLock) {
            mToken = token;
        }
    }

    /**
     * Notifies that the publisher services are ready.
     */
    protected abstract void onVmsPublisherServiceReady();

    /**
     * Publishers need to implement this method to receive notifications of subscription changes.
     *
     * @param subscriptionState the state of the subscriptions.
     */
    public abstract void onVmsSubscriptionChange(VmsSubscriptionState subscriptionState);

    /**
     * Uses the VmsPublisherService binder to publish messages.
     *
     * @param layer   the layer to publish to.
     * @param payload the message to be sent.
     * @param publisherId the ID that got assigned to the publisher that published the message by
     *                    VMS core.
     * @return if the call to the method VmsPublisherService.publish was successful.
     */
    public final void publish(VmsLayer layer, int publisherId, byte[] payload) {
        if (DBG) {
            Log.d(TAG, "Publishing for layer : " + layer);
        }

        IBinder token = getTokenForPublisherServiceThreadSafe();

        try {
            mVmsPublisherService.publish(token, layer, publisherId, payload);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Uses the VmsPublisherService binder to set the layers offering.
     *
     * @param offering the layers that the publisher may publish.
     * @return if the call to VmsPublisherService.setLayersOffering was successful.
     */
    public final void setLayersOffering(VmsLayersOffering offering) {
        if (DBG) {
            Log.d(TAG, "Setting layers offering : " + offering);
        }

        IBinder token = getTokenForPublisherServiceThreadSafe();

        try {
            mVmsPublisherService.setLayersOffering(token, offering);
            VmsOperationRecorder.get().setLayersOffering(offering);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    private IBinder getTokenForPublisherServiceThreadSafe() {
        if (mVmsPublisherService == null) {
            throw new IllegalStateException("VmsPublisherService not set.");
        }

        IBinder token;
        synchronized (mLock) {
            token = mToken;
        }
        if (token == null) {
            throw new IllegalStateException("VmsPublisherService does not have a valid token.");
        }
        return token;
    }

    public final int getPublisherId(byte[] publisherInfo) {
        if (mVmsPublisherService == null) {
            throw new IllegalStateException("VmsPublisherService not set.");
        }
        Integer publisherId = null;
        try {
            Log.i(TAG, "Getting publisher static ID");
            publisherId = mVmsPublisherService.getPublisherId(publisherInfo);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
        if (publisherId == null) {
            throw new IllegalStateException("VmsPublisherService cannot get a publisher static ID.");
        } else {
            VmsOperationRecorder.get().getPublisherId(publisherId);
        }
        return publisherId;
    }

    /**
     * Uses the VmsPublisherService binder to get the state of the subscriptions.
     *
     * @return list of layer/version or null in case of error.
     */
    public final @Nullable VmsSubscriptionState getSubscriptions() {
        if (mVmsPublisherService == null) {
            throw new IllegalStateException("VmsPublisherService not set.");
        }
        try {
            return mVmsPublisherService.getSubscriptions();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    private void setVmsPublisherService(IVmsPublisherService service) {
        mVmsPublisherService = service;
        onVmsPublisherServiceReady();
    }

    /**
     * Implements the interface that the VMS service uses to communicate with this client.
     */
    private static class VmsPublisherClientBinder extends IVmsPublisherClient.Stub {
        private final WeakReference<VmsPublisherClientService> mVmsPublisherClientService;
        @GuardedBy("mSequenceLock")
        private long mSequence = -1;
        private final Object mSequenceLock = new Object();

        public VmsPublisherClientBinder(VmsPublisherClientService vmsPublisherClientService) {
            mVmsPublisherClientService = new WeakReference<>(vmsPublisherClientService);
        }

        @Override
        public void setVmsPublisherService(IBinder token, IVmsPublisherService service)
                throws RemoteException {
            VmsPublisherClientService vmsPublisherClientService = mVmsPublisherClientService.get();
            if (vmsPublisherClientService == null) return;
            if (DBG) {
                Log.d(TAG, "setting VmsPublisherService.");
            }
            Handler handler = vmsPublisherClientService.mHandler;
            handler.sendMessage(
                    handler.obtainMessage(VmsEventHandler.SET_SERVICE_CALLBACK, service));
            vmsPublisherClientService.setToken(token);
        }

        @Override
        public void onVmsSubscriptionChange(VmsSubscriptionState subscriptionState)
                throws RemoteException {
            VmsPublisherClientService vmsPublisherClientService = mVmsPublisherClientService.get();
            if (vmsPublisherClientService == null) return;
            if (DBG) {
                Log.d(TAG, "subscription event: " + subscriptionState);
            }
            synchronized (mSequenceLock) {
                if (subscriptionState.getSequenceNumber() <= mSequence) {
                    Log.w(TAG, "Sequence out of order. Current sequence = " + mSequence
                            + "; expected new sequence = " + subscriptionState.getSequenceNumber());
                    // Do not propagate old notifications.
                    return;
                } else {
                    mSequence = subscriptionState.getSequenceNumber();
                }
            }
            Handler handler = vmsPublisherClientService.mHandler;
            handler.sendMessage(
                    handler.obtainMessage(VmsEventHandler.ON_SUBSCRIPTION_CHANGE_EVENT,
                            subscriptionState));
        }
    }

    /**
     * Receives events from the binder thread and dispatches them.
     */
    private final static class VmsEventHandler extends Handler {
        /** Constants handled in the handler */
        private static final int ON_SUBSCRIPTION_CHANGE_EVENT = 0;
        private static final int SET_SERVICE_CALLBACK = 1;

        private final WeakReference<VmsPublisherClientService> mVmsPublisherClientService;

        VmsEventHandler(VmsPublisherClientService service) {
            super(Looper.getMainLooper());
            mVmsPublisherClientService = new WeakReference<>(service);
        }

        @Override
        public void handleMessage(Message msg) {
            VmsPublisherClientService service = mVmsPublisherClientService.get();
            if (service == null) return;
            switch (msg.what) {
                case ON_SUBSCRIPTION_CHANGE_EVENT:
                    VmsSubscriptionState subscriptionState = (VmsSubscriptionState) msg.obj;
                    service.onVmsSubscriptionChange(subscriptionState);
                    break;
                case SET_SERVICE_CALLBACK:
                    service.setVmsPublisherService((IVmsPublisherService) msg.obj);
                    break;
                default:
                    Log.e(TAG, "Event type not handled:  " + msg.what);
                    break;
            }
        }
    }
}
