/*
 * 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 com.android.car;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.car.Car;
import android.car.diagnostic.CarDiagnosticEvent;
import android.car.diagnostic.CarDiagnosticManager;
import android.car.diagnostic.ICarDiagnostic;
import android.car.diagnostic.ICarDiagnosticEventListener;
import android.content.Context;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.ArrayMap;
import android.util.IndentingPrintWriter;
import android.util.Slog;

import com.android.car.Listeners.ClientWithRate;
import com.android.car.hal.DiagnosticHalService;
import com.android.car.hal.DiagnosticHalService.DiagnosticCapabilities;
import com.android.car.internal.CarPermission;
import com.android.internal.annotations.GuardedBy;

import java.util.Arrays;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;

/** @hide */
public class CarDiagnosticService extends ICarDiagnostic.Stub
        implements CarServiceBase, DiagnosticHalService.DiagnosticListener {
    /** lock to access diagnostic structures */
    private final ReentrantLock mDiagnosticLock = new ReentrantLock();
    /** hold clients callback */
    @GuardedBy("mDiagnosticLock")
    private final LinkedList<DiagnosticClient> mClients = new LinkedList<>();

    /** key: diagnostic type. */
    @GuardedBy("mDiagnosticLock")
    private final HashMap<Integer, Listeners<DiagnosticClient>> mDiagnosticListeners =
        new HashMap<>();

    /** the latest live frame data. */
    @GuardedBy("mDiagnosticLock")
    private final LiveFrameRecord mLiveFrameDiagnosticRecord = new LiveFrameRecord(mDiagnosticLock);

    /** the latest freeze frame data (key: DTC) */
    @GuardedBy("mDiagnosticLock")
    private final FreezeFrameRecord mFreezeFrameDiagnosticRecords = new FreezeFrameRecord(
        mDiagnosticLock);

    private final DiagnosticHalService mDiagnosticHal;

    private final Context mContext;

    private final CarPermission mDiagnosticReadPermission;

    private final CarPermission mDiagnosticClearPermission;

    public CarDiagnosticService(Context context, DiagnosticHalService diagnosticHal) {
        mContext = context;
        mDiagnosticHal = diagnosticHal;
        mDiagnosticReadPermission = new CarPermission(mContext,
                Car.PERMISSION_CAR_DIAGNOSTIC_READ_ALL);
        mDiagnosticClearPermission = new CarPermission(mContext,
                Car.PERMISSION_CAR_DIAGNOSTIC_CLEAR);
    }

    @Override
    public void init() {
        mDiagnosticLock.lock();
        try {
            mDiagnosticHal.setDiagnosticListener(this);
            setInitialLiveFrame();
            setInitialFreezeFrames();
        } finally {
            mDiagnosticLock.unlock();
        }
    }

    @Nullable
    private CarDiagnosticEvent setInitialLiveFrame() {
        CarDiagnosticEvent liveFrame = null;
        if(mDiagnosticHal.getDiagnosticCapabilities().isLiveFrameSupported()) {
            liveFrame = setRecentmostLiveFrame(mDiagnosticHal.getCurrentLiveFrame());
        }
        return liveFrame;
    }

    private void setInitialFreezeFrames() {
        if(mDiagnosticHal.getDiagnosticCapabilities().isFreezeFrameSupported() &&
            mDiagnosticHal.getDiagnosticCapabilities().isFreezeFrameInfoSupported()) {
            long[] timestamps = mDiagnosticHal.getFreezeFrameTimestamps();
            if (timestamps != null) {
                for (long timestamp : timestamps) {
                    setRecentmostFreezeFrame(mDiagnosticHal.getFreezeFrame(timestamp));
                }
            }
        }
    }

    @Nullable
    private CarDiagnosticEvent setRecentmostLiveFrame(final CarDiagnosticEvent event) {
        if (event != null) {
            return mLiveFrameDiagnosticRecord.update(event.checkLiveFrame());
        }
        return null;
    }

    @Nullable
    private CarDiagnosticEvent setRecentmostFreezeFrame(final CarDiagnosticEvent event) {
        if (event != null) {
            return mFreezeFrameDiagnosticRecords.update(event.checkFreezeFrame());
        }
        return null;
    }

    @Override
    public void release() {
        mDiagnosticLock.lock();
        try {
            mDiagnosticListeners.forEach(
                    (Integer frameType, Listeners diagnosticListeners) ->
                            diagnosticListeners.release());
            mDiagnosticListeners.clear();
            mLiveFrameDiagnosticRecord.disableIfNeeded();
            mFreezeFrameDiagnosticRecords.disableIfNeeded();
            mClients.clear();
        } finally {
            mDiagnosticLock.unlock();
        }
    }

    private void processDiagnosticData(List<CarDiagnosticEvent> events) {
        ArrayMap<CarDiagnosticService.DiagnosticClient, List<CarDiagnosticEvent>> eventsByClient =
                new ArrayMap<>();

        Listeners<DiagnosticClient> listeners = null;

        mDiagnosticLock.lock();
        for (CarDiagnosticEvent event : events) {
            if (event.isLiveFrame()) {
                // record recent-most live frame information
                setRecentmostLiveFrame(event);
                listeners = mDiagnosticListeners.get(CarDiagnosticManager.FRAME_TYPE_LIVE);
            } else if (event.isFreezeFrame()) {
                setRecentmostFreezeFrame(event);
                listeners = mDiagnosticListeners.get(CarDiagnosticManager.FRAME_TYPE_FREEZE);
            } else {
                Slog.w(
                        CarLog.TAG_DIAGNOSTIC,
                        String.format("received unknown diagnostic event: %s", event));
                continue;
            }

            if (null != listeners) {
                for (ClientWithRate<DiagnosticClient> clientWithRate : listeners.getClients()) {
                    DiagnosticClient client = clientWithRate.getClient();
                    List<CarDiagnosticEvent> clientEvents = eventsByClient.computeIfAbsent(client,
                            (DiagnosticClient diagnosticClient) -> new LinkedList<>());
                    clientEvents.add(event);
                }
            }
        }
        mDiagnosticLock.unlock();

        for (ArrayMap.Entry<CarDiagnosticService.DiagnosticClient, List<CarDiagnosticEvent>> entry :
                eventsByClient.entrySet()) {
            CarDiagnosticService.DiagnosticClient client = entry.getKey();
            List<CarDiagnosticEvent> clientEvents = entry.getValue();

            client.dispatchDiagnosticUpdate(clientEvents);
        }
    }

    /** Received diagnostic data from car. */
    @Override
    public void onDiagnosticEvents(List<CarDiagnosticEvent> events) {
        processDiagnosticData(events);
    }

    @Override
    public boolean registerOrUpdateDiagnosticListener(int frameType, int rate,
                ICarDiagnosticEventListener listener) {
        boolean shouldStartDiagnostics = false;
        CarDiagnosticService.DiagnosticClient diagnosticClient = null;
        Integer oldRate = null;
        Listeners<DiagnosticClient> diagnosticListeners = null;
        mDiagnosticLock.lock();
        try {
            mDiagnosticReadPermission.assertGranted();
            diagnosticClient = findDiagnosticClientLocked(listener);
            Listeners.ClientWithRate<DiagnosticClient> diagnosticClientWithRate = null;
            if (diagnosticClient == null) {
                diagnosticClient = new DiagnosticClient(listener);
                try {
                    listener.asBinder().linkToDeath(diagnosticClient, 0);
                } catch (RemoteException e) {
                    Slog.w(
                            CarLog.TAG_DIAGNOSTIC,
                            String.format(
                                    "received RemoteException trying to register listener for %s",
                                    frameType));
                    return false;
                }
                mClients.add(diagnosticClient);
            }
            diagnosticListeners = mDiagnosticListeners.get(frameType);
            if (diagnosticListeners == null) {
                diagnosticListeners = new Listeners<>(rate);
                mDiagnosticListeners.put(frameType, diagnosticListeners);
                shouldStartDiagnostics = true;
            } else {
                oldRate = diagnosticListeners.getRate();
                diagnosticClientWithRate =
                        diagnosticListeners.findClientWithRate(diagnosticClient);
            }
            if (diagnosticClientWithRate == null) {
                diagnosticClientWithRate =
                        new ClientWithRate<>(diagnosticClient, rate);
                diagnosticListeners.addClientWithRate(diagnosticClientWithRate);
            } else {
                diagnosticClientWithRate.setRate(rate);
            }
            if (diagnosticListeners.getRate() > rate) {
                diagnosticListeners.setRate(rate);
                shouldStartDiagnostics = true;
            }
            diagnosticClient.addDiagnostic(frameType);
        } finally {
            mDiagnosticLock.unlock();
        }
        Slog.i(
                CarLog.TAG_DIAGNOSTIC,
                String.format(
                        "shouldStartDiagnostics = %s for %s at rate %d",
                        shouldStartDiagnostics, frameType, rate));
        // start diagnostic outside lock as it can take time.
        if (shouldStartDiagnostics) {
            if (!startDiagnostic(frameType, rate)) {
                // failed. so remove from active diagnostic list.
                Slog.w(CarLog.TAG_DIAGNOSTIC, "startDiagnostic failed");
                mDiagnosticLock.lock();
                try {
                    diagnosticClient.removeDiagnostic(frameType);
                    if (oldRate != null) {
                        diagnosticListeners.setRate(oldRate);
                    } else {
                        mDiagnosticListeners.remove(frameType);
                    }
                } finally {
                    mDiagnosticLock.unlock();
                }
                return false;
            }
        }
        return true;
    }

    private boolean startDiagnostic(int frameType, int rate) {
        Slog.i(CarLog.TAG_DIAGNOSTIC, "starting diagnostic " + frameType + " at rate " + rate);
        DiagnosticHalService diagnosticHal = getDiagnosticHal();
        if (diagnosticHal != null) {
            if (!diagnosticHal.isReady()) {
                Slog.w(CarLog.TAG_DIAGNOSTIC, "diagnosticHal not ready");
                return false;
            }
            switch (frameType) {
                case CarDiagnosticManager.FRAME_TYPE_LIVE:
                    if (mLiveFrameDiagnosticRecord.isEnabled()) {
                        return true;
                    }
                    if (diagnosticHal.requestDiagnosticStart(CarDiagnosticManager.FRAME_TYPE_LIVE,
                            rate)) {
                        mLiveFrameDiagnosticRecord.enable();
                        return true;
                    }
                    break;
                case CarDiagnosticManager.FRAME_TYPE_FREEZE:
                    if (mFreezeFrameDiagnosticRecords.isEnabled()) {
                        return true;
                    }
                    if (diagnosticHal.requestDiagnosticStart(CarDiagnosticManager.FRAME_TYPE_FREEZE,
                            rate)) {
                        mFreezeFrameDiagnosticRecords.enable();
                        return true;
                    }
                    break;
            }
        }
        return false;
    }

    @Override
    public void unregisterDiagnosticListener(
            int frameType, ICarDiagnosticEventListener listener) {
        boolean shouldStopDiagnostic = false;
        boolean shouldRestartDiagnostic = false;
        int newRate = 0;
        mDiagnosticLock.lock();
        try {
            DiagnosticClient diagnosticClient = findDiagnosticClientLocked(listener);
            if (diagnosticClient == null) {
                Slog.i(
                        CarLog.TAG_DIAGNOSTIC,
                        String.format(
                                "trying to unregister diagnostic client %s for %s which is not registered",
                                listener, frameType));
                // never registered or already unregistered.
                return;
            }
            diagnosticClient.removeDiagnostic(frameType);
            if (diagnosticClient.getNumberOfActiveDiagnostic() == 0) {
                diagnosticClient.release();
                mClients.remove(diagnosticClient);
            }
            Listeners<DiagnosticClient> diagnosticListeners = mDiagnosticListeners.get(frameType);
            if (diagnosticListeners == null) {
                // diagnostic not active
                return;
            }
            ClientWithRate<DiagnosticClient> clientWithRate =
                    diagnosticListeners.findClientWithRate(diagnosticClient);
            if (clientWithRate == null) {
                return;
            }
            diagnosticListeners.removeClientWithRate(clientWithRate);
            if (diagnosticListeners.getNumberOfClients() == 0) {
                shouldStopDiagnostic = true;
                mDiagnosticListeners.remove(frameType);
            } else if (diagnosticListeners.updateRate()) { // rate changed
                newRate = diagnosticListeners.getRate();
                shouldRestartDiagnostic = true;
            }
        } finally {
            mDiagnosticLock.unlock();
        }
        Slog.i(
                CarLog.TAG_DIAGNOSTIC,
                String.format(
                        "shouldStopDiagnostic = %s, shouldRestartDiagnostic = %s for type %s",
                        shouldStopDiagnostic, shouldRestartDiagnostic, frameType));
        if (shouldStopDiagnostic) {
            stopDiagnostic(frameType);
        } else if (shouldRestartDiagnostic) {
            startDiagnostic(frameType, newRate);
        }
    }

    private void stopDiagnostic(int frameType) {
        DiagnosticHalService diagnosticHal = getDiagnosticHal();
        if (diagnosticHal == null || !diagnosticHal.isReady()) {
            Slog.w(CarLog.TAG_DIAGNOSTIC, "diagnosticHal not ready");
            return;
        }
        switch (frameType) {
            case CarDiagnosticManager.FRAME_TYPE_LIVE:
                if (mLiveFrameDiagnosticRecord.disableIfNeeded())
                    diagnosticHal.requestDiagnosticStop(CarDiagnosticManager.FRAME_TYPE_LIVE);
                break;
            case CarDiagnosticManager.FRAME_TYPE_FREEZE:
                if (mFreezeFrameDiagnosticRecords.disableIfNeeded())
                    diagnosticHal.requestDiagnosticStop(CarDiagnosticManager.FRAME_TYPE_FREEZE);
                break;
        }
    }

    private DiagnosticHalService getDiagnosticHal() {
        return mDiagnosticHal;
    }

    // Expose DiagnosticCapabilities
    public boolean isLiveFrameSupported() {
        return getDiagnosticHal().getDiagnosticCapabilities().isLiveFrameSupported();
    }

    public boolean isFreezeFrameNotificationSupported() {
        return getDiagnosticHal().getDiagnosticCapabilities().isFreezeFrameSupported();
    }

    public boolean isGetFreezeFrameSupported() {
        DiagnosticCapabilities diagnosticCapabilities =
                getDiagnosticHal().getDiagnosticCapabilities();
        return diagnosticCapabilities.isFreezeFrameInfoSupported() &&
                diagnosticCapabilities.isFreezeFrameSupported();
    }

    public boolean isClearFreezeFramesSupported() {
        DiagnosticCapabilities diagnosticCapabilities =
            getDiagnosticHal().getDiagnosticCapabilities();
        return diagnosticCapabilities.isFreezeFrameClearSupported() &&
            diagnosticCapabilities.isFreezeFrameSupported();
    }

    public boolean isSelectiveClearFreezeFramesSupported() {
        DiagnosticCapabilities diagnosticCapabilities =
            getDiagnosticHal().getDiagnosticCapabilities();
        return isClearFreezeFramesSupported() &&
                diagnosticCapabilities.isSelectiveClearFreezeFramesSupported();
    }

    // ICarDiagnostic implementations

    @Override
    public CarDiagnosticEvent getLatestLiveFrame() {
        mLiveFrameDiagnosticRecord.lock();
        CarDiagnosticEvent liveFrame = mLiveFrameDiagnosticRecord.getLastEvent();
        mLiveFrameDiagnosticRecord.unlock();
        return liveFrame;
    }

    @Override
    public long[] getFreezeFrameTimestamps() {
        mFreezeFrameDiagnosticRecords.lock();
        long[] timestamps = mFreezeFrameDiagnosticRecords.getFreezeFrameTimestamps();
        mFreezeFrameDiagnosticRecords.unlock();
        return timestamps;
    }

    @Override
    @Nullable
    public CarDiagnosticEvent getFreezeFrame(long timestamp) {
        mFreezeFrameDiagnosticRecords.lock();
        CarDiagnosticEvent freezeFrame = mFreezeFrameDiagnosticRecords.getEvent(timestamp);
        mFreezeFrameDiagnosticRecords.unlock();
        return freezeFrame;
    }

    @Override
    public boolean clearFreezeFrames(long... timestamps) {
        mDiagnosticClearPermission.assertGranted();
        if (!isClearFreezeFramesSupported())
            return false;
        if (timestamps != null && timestamps.length != 0) {
            if (!isSelectiveClearFreezeFramesSupported()) {
                return false;
            }
        }
        mFreezeFrameDiagnosticRecords.lock();
        mDiagnosticHal.clearFreezeFrames(timestamps);
        mFreezeFrameDiagnosticRecords.clearEvents();
        mFreezeFrameDiagnosticRecords.unlock();
        return true;
    }

    /**
     * Find DiagnosticClient from client list and return it. This should be called with mClients
     * locked.
     *
     * @param listener
     * @return null if not found.
     */
    @GuardedBy("mDiagnosticLock")
    private CarDiagnosticService.DiagnosticClient findDiagnosticClientLocked(
            ICarDiagnosticEventListener listener) {
        IBinder binder = listener.asBinder();
        for (DiagnosticClient diagnosticClient : mClients) {
            if (diagnosticClient.isHoldingListenerBinder(binder)) {
                return diagnosticClient;
            }
        }
        return null;
    }

    private void removeClient(DiagnosticClient diagnosticClient) {
        mDiagnosticLock.lock();
        try {
            for (int diagnostic : diagnosticClient.getDiagnosticArray()) {
                unregisterDiagnosticListener(
                        diagnostic, diagnosticClient.getICarDiagnosticEventListener());
            }
            mClients.remove(diagnosticClient);
        } finally {
            mDiagnosticLock.unlock();
        }
    }

    /** internal instance for pending client request */
    private class DiagnosticClient implements Listeners.IListener {
        /** callback for diagnostic events */
        private final ICarDiagnosticEventListener mListener;

        private final Set<Integer> mActiveDiagnostics = new HashSet<>();

        /** when false, it is already released */
        private volatile boolean mActive = true;

        DiagnosticClient(ICarDiagnosticEventListener listener) {
            this.mListener = listener;
        }

        @Override
        public boolean equals(Object o) {
            return o instanceof DiagnosticClient
                && mListener.asBinder()
                == ((DiagnosticClient) o).mListener.asBinder();
        }

        boolean isHoldingListenerBinder(IBinder listenerBinder) {
            return mListener.asBinder() == listenerBinder;
        }

        void addDiagnostic(int frameType) {
            mActiveDiagnostics.add(frameType);
        }

        void removeDiagnostic(int frameType) {
            mActiveDiagnostics.remove(frameType);
        }

        int getNumberOfActiveDiagnostic() {
            return mActiveDiagnostics.size();
        }

        int[] getDiagnosticArray() {
            return mActiveDiagnostics.stream().mapToInt(Integer::intValue).toArray();
        }

        ICarDiagnosticEventListener getICarDiagnosticEventListener() {
            return mListener;
        }

        /** Client dead. should remove all diagnostic requests from client */
        @Override
        public void binderDied() {
            mListener.asBinder().unlinkToDeath(this, 0);
            removeClient(this);
        }

        void dispatchDiagnosticUpdate(List<CarDiagnosticEvent> events) {
            if (events.size() != 0 && mActive) {
                try {
                    mListener.onDiagnosticEvents(events);
                } catch (RemoteException e) {
                    //ignore. crash will be handled by death handler
                }
            }
        }

        @Override
        public void release() {
            if (mActive) {
                mListener.asBinder().unlinkToDeath(this, 0);
                mActiveDiagnostics.clear();
                mActive = false;
            }
        }
    }

    private static abstract class DiagnosticRecord {
        private final ReentrantLock mLock;
        protected boolean mEnabled = false;

        DiagnosticRecord(ReentrantLock lock) {
            mLock = lock;
        }

        void lock() {
            mLock.lock();
        }

        void unlock() {
            mLock.unlock();
        }

        boolean isEnabled() {
            return mEnabled;
        }

        void enable() {
            mEnabled = true;
        }

        abstract boolean disableIfNeeded();
        abstract CarDiagnosticEvent update(CarDiagnosticEvent newEvent);
    }

    private static class LiveFrameRecord extends DiagnosticRecord {
        /** Store the most recent live-frame. */
        CarDiagnosticEvent mLastEvent = null;

        LiveFrameRecord(ReentrantLock lock) {
            super(lock);
        }

        @Override
        boolean disableIfNeeded() {
            if (!mEnabled) return false;
            mEnabled = false;
            mLastEvent = null;
            return true;
        }

        @Override
        CarDiagnosticEvent update(@NonNull CarDiagnosticEvent newEvent) {
            Objects.requireNonNull(newEvent);
            if((null == mLastEvent) || mLastEvent.isEarlierThan(newEvent))
                mLastEvent = newEvent;
            return mLastEvent;
        }

        CarDiagnosticEvent getLastEvent() {
            return mLastEvent;
        }
    }

    private static class FreezeFrameRecord extends DiagnosticRecord {
        /** Store the timestamp --> freeze frame mapping. */
        HashMap<Long, CarDiagnosticEvent> mEvents = new HashMap<>();

        FreezeFrameRecord(ReentrantLock lock) {
            super(lock);
        }

        @Override
        boolean disableIfNeeded() {
            if (!mEnabled) return false;
            mEnabled = false;
            clearEvents();
            return true;
        }

        void clearEvents() {
            mEvents.clear();
        }

        @Override
        CarDiagnosticEvent update(@NonNull CarDiagnosticEvent newEvent) {
            mEvents.put(newEvent.timestamp, newEvent);
            return newEvent;
        }

        long[] getFreezeFrameTimestamps() {
            return mEvents.keySet().stream().mapToLong(Long::longValue).toArray();
        }

        CarDiagnosticEvent getEvent(long timestamp) {
            return mEvents.get(timestamp);
        }

        Iterable<CarDiagnosticEvent> getEvents() {
            return mEvents.values();
        }
    }

    @Override
    public void dump(IndentingPrintWriter writer) {
        writer.println("*CarDiagnosticService*");
        writer.println("**last events for diagnostics**");
        if (null != mLiveFrameDiagnosticRecord.getLastEvent()) {
            writer.println("last live frame event: ");
            writer.println(mLiveFrameDiagnosticRecord.getLastEvent());
        }
        writer.println("freeze frame events: ");
        mFreezeFrameDiagnosticRecords.getEvents().forEach(writer::println);
        writer.println("**clients**");
        try {
            for (DiagnosticClient client : mClients) {
                if (client != null) {
                    try {
                        writer.println(
                                "binder:"
                                        + client.mListener
                                        + " active diagnostics:"
                                        + Arrays.toString(client.getDiagnosticArray()));
                    } catch (ConcurrentModificationException e) {
                        writer.println("concurrent modification happened");
                    }
                } else {
                    writer.println("null client");
                }
            }
        } catch (ConcurrentModificationException e) {
            writer.println("concurrent modification happened");
        }
        writer.println("**diagnostic listeners**");
        try {
            for (int diagnostic : mDiagnosticListeners.keySet()) {
                Listeners diagnosticListeners = mDiagnosticListeners.get(diagnostic);
                if (diagnosticListeners != null) {
                    writer.println(
                            " Diagnostic:"
                                    + diagnostic
                                    + " num client:"
                                    + diagnosticListeners.getNumberOfClients()
                                    + " rate:"
                                    + diagnosticListeners.getRate());
                }
            }
        } catch (ConcurrentModificationException e) {
            writer.println("concurrent modification happened");
        }
    }
}
