/*
 * Copyright (C) 2021 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.android.server.uwb;

import android.annotation.NonNull;
import android.content.AttributionSource;
import android.content.ContentResolver;
import android.content.Context;
import android.os.Binder;
import android.os.IBinder;
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.provider.Settings;
import android.util.ArrayMap;
import android.util.Log;
import android.uwb.AdapterState;
import android.uwb.IUwbAdapter;
import android.uwb.IUwbAdapterStateCallbacks;
import android.uwb.IUwbRangingCallbacks;
import android.uwb.RangingReport;
import android.uwb.RangingSession;
import android.uwb.SessionHandle;

import com.android.internal.annotations.GuardedBy;

import java.util.Map;

/**
 * Implementation of {@link android.uwb.IUwbAdapter} binder service.
 */
public class UwbServiceImpl extends IUwbAdapter.Stub implements IBinder.DeathRecipient{
    private static final String TAG = "UwbServiceImpl";

    private final Context mContext;
    private final UwbInjector mUwbInjector;
    /**
     * Map for storing the callbacks wrapper for each session.
     */
    @GuardedBy("mCallbacksMap")
    private final Map<SessionHandle, UwbRangingCallbacksWrapper> mCallbacksMap = new ArrayMap<>();

    /**
     * Used for caching the vendor implementation of {@link IUwbAdapter} interface.
     */
    private IUwbAdapter mVendorUwbAdapter;

    /**
     * Wrapper for callback registered with vendor service. This wrapper is needed for performing
     * permission check before sending the callback to the external app.
     *
     * Access to these callbacks are synchronized.
     */
    private class UwbRangingCallbacksWrapper extends IUwbRangingCallbacks.Stub
            implements IBinder.DeathRecipient {
        private final AttributionSource mAttributionSource;
        private final SessionHandle mSessionHandle;
        private final IUwbRangingCallbacks mExternalCb;
        private boolean mIsValid;

        UwbRangingCallbacksWrapper(@NonNull AttributionSource attributionSource,
                @NonNull SessionHandle sessionHandle,
                @NonNull IUwbRangingCallbacks externalCb) {
            mAttributionSource = attributionSource;
            mSessionHandle = sessionHandle;
            mExternalCb = externalCb;
            mIsValid = true;

            // Link to death for external callback.
            linkToDeath();
        }

        private void linkToDeath() {
            IBinder binder = mExternalCb.asBinder();
            try {
                binder.linkToDeath(this, 0);
            } catch (RemoteException e) {
                Log.e(TAG, "Unable to link to client death event.", e);
            }
        }

        private void removeClientAndUnlinkToDeath() {
            // Remove from the map.
            synchronized (mCallbacksMap) {
                mCallbacksMap.remove(mSessionHandle);
            }
            IBinder binder = mExternalCb.asBinder();
            binder.unlinkToDeath(this, 0);
            mIsValid = false;
        }


        @Override
        public synchronized void onRangingOpened(SessionHandle sessionHandle)
                throws RemoteException {
            if (!mIsValid) return;
            mExternalCb.onRangingOpened(sessionHandle);
        }

        @Override
        public synchronized void onRangingOpenFailed(SessionHandle sessionHandle,
                int reason, PersistableBundle parameters) throws RemoteException {
            if (!mIsValid) return;
            mExternalCb.onRangingOpenFailed(sessionHandle, reason, parameters);
        }

        @Override
        public synchronized void onRangingStarted(SessionHandle sessionHandle,
                PersistableBundle parameters)
                throws RemoteException {
            if (!mIsValid) return;
            mExternalCb.onRangingStarted(sessionHandle, parameters);
        }

        @Override
        public synchronized void onRangingStartFailed(SessionHandle sessionHandle,
                int reason, PersistableBundle parameters) throws RemoteException {
            if (!mIsValid) return;
            mExternalCb.onRangingStartFailed(sessionHandle, reason, parameters);
        }

        @Override
        public synchronized void onRangingReconfigured(SessionHandle sessionHandle,
                PersistableBundle parameters)
                throws RemoteException {
            if (!mIsValid) return;
            mExternalCb.onRangingReconfigured(sessionHandle, parameters);
        }

        @Override
        public synchronized void onRangingReconfigureFailed(SessionHandle sessionHandle,
                int reason, PersistableBundle parameters) throws RemoteException {
            if (!mIsValid) return;
            mExternalCb.onRangingReconfigureFailed(sessionHandle, reason, parameters);
        }

        @Override
        public synchronized void onRangingStopped(SessionHandle sessionHandle, int reason,
                PersistableBundle parameters)
                throws RemoteException {
            if (!mIsValid) return;
            mExternalCb.onRangingStopped(sessionHandle, reason, parameters);
        }

        @Override
        public synchronized void onRangingStopFailed(SessionHandle sessionHandle, int reason,
                PersistableBundle parameters) throws RemoteException {
            if (!mIsValid) return;
            mExternalCb.onRangingStopFailed(sessionHandle, reason, parameters);
        }

        @Override
        public synchronized void onRangingClosed(SessionHandle sessionHandle, int reason,
                PersistableBundle parameters) throws RemoteException {
            if (!mIsValid) return;
            mExternalCb.onRangingClosed(sessionHandle, reason, parameters);
            removeClientAndUnlinkToDeath();
        }

        @Override
        public synchronized void onRangingResult(SessionHandle sessionHandle,
                RangingReport rangingReport)
                throws RemoteException {
            if (!mIsValid) return;
            boolean permissionGranted = Binder.withCleanCallingIdentity(
                    () -> mUwbInjector.checkUwbRangingPermissionForDataDelivery(
                            mAttributionSource, "uwb ranging result"));
            if (!permissionGranted) {
                Log.e(TAG, "Not delivering ranging result because of permission denial"
                        + mSessionHandle);
                return;
            }
            mExternalCb.onRangingResult(sessionHandle, rangingReport);
        }

        @Override
        public synchronized void binderDied() {
            if (!mIsValid) return;
            Log.i(TAG, "Client died: ending session: " + mSessionHandle);
            try {
                removeClientAndUnlinkToDeath();
                stopRanging(mSessionHandle);
                closeRanging(mSessionHandle);
            } catch (RemoteException e) {
                Log.e(TAG, "Remote exception while handling client death", e);
            }
        }
    }

    private void linkToVendorServiceDeath() {
        IBinder binder = mVendorUwbAdapter.asBinder();
        try {
            binder.linkToDeath(this, 0);
        } catch (RemoteException e) {
            Log.e(TAG, "Unable to link to vendor service death event.", e);
        }
    }

    @Override
    public void binderDied() {
        Log.i(TAG, "Vendor service died: sending session close callbacks");
        synchronized (mCallbacksMap) {
            for (Map.Entry<SessionHandle, UwbRangingCallbacksWrapper> e : mCallbacksMap.entrySet()) {
                try {
                    e.getValue().mExternalCb.onRangingClosed(
                            e.getKey(), RangingSession.Callback.REASON_UNKNOWN,
                            new PersistableBundle());
                } catch (RemoteException ex) {
                    Log.e(TAG, "Failed to send session close callback " + e.getKey(), ex);
                }
            }
            // Clear all sessions.
            mCallbacksMap.clear();
        }
        mVendorUwbAdapter = null;
    }

    private synchronized IUwbAdapter getVendorUwbAdapter()
            throws IllegalStateException, RemoteException {
        if (mVendorUwbAdapter != null) return mVendorUwbAdapter;
        mVendorUwbAdapter = mUwbInjector.getVendorService();
        if (mVendorUwbAdapter == null) {
            throw new IllegalStateException("No vendor service found!");
        }
        Log.i(TAG, "Retrieved vendor service");
        mVendorUwbAdapter.setEnabled(mUwbInjector.isPersistedUwbStateEnabled());
        linkToVendorServiceDeath();
        return mVendorUwbAdapter;
    }

    UwbServiceImpl(@NonNull Context context, @NonNull UwbInjector uwbInjector) {
        mContext = context;
        mUwbInjector = uwbInjector;
    }

    private void enforceUwbPrivilegedPermission() {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.UWB_PRIVILEGED,
                "UwbService");
    }

    @Override
    public void registerAdapterStateCallbacks(IUwbAdapterStateCallbacks adapterStateCallbacks)
            throws RemoteException {
        enforceUwbPrivilegedPermission();
        getVendorUwbAdapter().registerAdapterStateCallbacks(adapterStateCallbacks);
    }

    @Override
    public void unregisterAdapterStateCallbacks(IUwbAdapterStateCallbacks adapterStateCallbacks)
            throws RemoteException {
        enforceUwbPrivilegedPermission();
        getVendorUwbAdapter().unregisterAdapterStateCallbacks(adapterStateCallbacks);
    }

    @Override
    public long getTimestampResolutionNanos() throws RemoteException {
        enforceUwbPrivilegedPermission();
        return getVendorUwbAdapter().getTimestampResolutionNanos();
    }

    @Override
    public PersistableBundle getSpecificationInfo() throws RemoteException {
        enforceUwbPrivilegedPermission();
        return getVendorUwbAdapter().getSpecificationInfo();
    }

    @Override
    public void openRanging(AttributionSource attributionSource,
            SessionHandle sessionHandle, IUwbRangingCallbacks rangingCallbacks,
            PersistableBundle parameters) throws RemoteException {
        enforceUwbPrivilegedPermission();
        mUwbInjector.enforceUwbRangingPermissionForPreflight(attributionSource);

        UwbRangingCallbacksWrapper wrapperCb =
                new UwbRangingCallbacksWrapper(attributionSource, sessionHandle, rangingCallbacks);
        synchronized (mCallbacksMap) {
            mCallbacksMap.put(sessionHandle, wrapperCb);
        }
        getVendorUwbAdapter().openRanging(attributionSource, sessionHandle, wrapperCb, parameters);
    }

    @Override
    public void startRanging(SessionHandle sessionHandle, PersistableBundle parameters)
            throws RemoteException {
        enforceUwbPrivilegedPermission();
        getVendorUwbAdapter().startRanging(sessionHandle, parameters);
    }

    @Override
    public void reconfigureRanging(SessionHandle sessionHandle, PersistableBundle parameters)
            throws RemoteException {
        enforceUwbPrivilegedPermission();
        getVendorUwbAdapter().reconfigureRanging(sessionHandle, parameters);
    }

    @Override
    public void stopRanging(SessionHandle sessionHandle) throws RemoteException {
        enforceUwbPrivilegedPermission();
        getVendorUwbAdapter().stopRanging(sessionHandle);
    }

    @Override
    public void closeRanging(SessionHandle sessionHandle) throws RemoteException {
        enforceUwbPrivilegedPermission();
        getVendorUwbAdapter().closeRanging(sessionHandle);
    }

    @Override
    public synchronized int getAdapterState() throws RemoteException {
        return getVendorUwbAdapter().getAdapterState();
    }

    @Override
    public synchronized void setEnabled(boolean enabled) throws RemoteException {
        persistUwbState(enabled);
        getVendorUwbAdapter().setEnabled(enabled);
    }

    private void persistUwbState(boolean enabled) {
        final ContentResolver cr = mContext.getContentResolver();
        int state = enabled ? AdapterState.STATE_ENABLED_ACTIVE : AdapterState.STATE_DISABLED;
        Settings.Global.putInt(cr, Settings.Global.UWB_ENABLED, state);
    }
}
