/*
 * Copyright (C) 2019 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.testapi;

import static android.car.hardware.property.CarPropertyEvent.PROPERTY_EVENT_PROPERTY_CHANGE;

import static java.lang.Integer.toHexString;

import android.annotation.Nullable;
import android.car.VehicleAreaType;
import android.car.VehiclePropertyType;
import android.car.hardware.CarPropertyConfig;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyEvent;
import android.car.hardware.property.ICarProperty;
import android.car.hardware.property.ICarPropertyEventListener;
import android.os.RemoteException;

import com.android.car.internal.PropertyPermissionMapping;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * This is fake implementation of the service which is used in
 * {@link android.car.hardware.property.CarPropertyManager}.
 *
 * @hide
 */
class FakeCarPropertyService extends ICarProperty.Stub implements CarPropertyController {
    private final Map<Integer, CarPropertyConfig> mConfigs = new HashMap<>();
    private final Map<PropKey, CarPropertyValue> mValues = new HashMap<>();

    private final PropertyPermissionMapping mPermissions = new PropertyPermissionMapping();

    // Contains a list of values that were set from the manager.
    private final ArrayList<CarPropertyValue<?>> mValuesSet = new ArrayList<>();

    // Mapping between propertyId and a set of listeners.
    private final Map<Integer, Set<ListenerInfo>> mListeners = new HashMap<>();

    @Override
    public void registerListener(int propId, float rate, ICarPropertyEventListener listener)
            throws RemoteException {
        Set<ListenerInfo> propListeners = mListeners.get(propId);
        if (propListeners == null) {
            propListeners = new HashSet<>();
            mListeners.put(propId, propListeners);
        }

        propListeners.add(new ListenerInfo(listener));
    }

    @Override
    public void unregisterListener(int propId, ICarPropertyEventListener listener)
            throws RemoteException {
        Set<ListenerInfo> propListeners = mListeners.get(propId);
        if (propListeners != null && propListeners.remove(new ListenerInfo(listener))) {
            if (propListeners.isEmpty()) {
                mListeners.remove(propId);
            }
        }
    }

    @Override
    public List<CarPropertyConfig> getPropertyList() throws RemoteException {
        return new ArrayList<>(mConfigs.values());
    }

    @Override
    public List<CarPropertyConfig> getPropertyConfigList(int[] propIds) {
        List<CarPropertyConfig> configs = new ArrayList<>(propIds.length);
        for (int prop : propIds) {
            CarPropertyConfig cfg = mConfigs.get(prop);
            if (cfg != null) {
                configs.add(cfg);
            }
        }
        return configs;
    }

    @Override
    public CarPropertyValue getProperty(int prop, int zone) throws RemoteException {
        return mValues.get(PropKey.of(prop, zone));
    }

    @Override
    public void setProperty(CarPropertyValue prop, ICarPropertyEventListener listener)
            throws RemoteException {
        mValues.put(PropKey.of(prop), prop);
        mValuesSet.add(prop);
        sendEvent(prop);
    }

    @Override
    public String getReadPermission(int propId) throws RemoteException {
        return mConfigs.containsKey(propId) ? mPermissions.getReadPermission(propId) : null;
    }

    @Override
    public String getWritePermission(int propId) throws RemoteException {
        return mConfigs.containsKey(propId) ? mPermissions.getWritePermission(propId) : null;
    }

    @Override
    public CarPropertyController addProperty(Integer propId, Object value) {
        int areaType = getVehicleAreaType(propId);
        Class<?> type = getPropertyType(propId);
        CarPropertyConfig.Builder<?> builder = CarPropertyConfig
                .newBuilder(type, propId, areaType);
        mConfigs.put(propId, builder.build());
        if (value != null) {
            updateValues(false, new CarPropertyValue<>(propId, 0, value));
        }

        return this;
    }

    @Override
    public CarPropertyController addProperty(CarPropertyConfig<?> config,
            @Nullable CarPropertyValue<?> value) {
        mConfigs.put(config.getPropertyId(), config);
        if (value != null) {
            updateValues(false, value);
        }
        return this;
    }

    @Override
    public void updateValues(boolean triggerListeners, CarPropertyValue<?>... propValues) {
        for (CarPropertyValue v : propValues) {
            mValues.put(PropKey.of(v), v);
            if (triggerListeners) {
                sendEvent(v);
            }
        }
    }

    private void sendEvent(CarPropertyValue v) {
        Set<ListenerInfo> listeners = mListeners.get(v.getPropertyId());
        if (listeners != null) {
            for (ListenerInfo listenerInfo : listeners) {
                List<CarPropertyEvent> events = new ArrayList<>();
                events.add(new CarPropertyEvent(PROPERTY_EVENT_PROPERTY_CHANGE, v));
                try {
                    listenerInfo.mListener.onEvent(events);
                } catch (RemoteException e) {
                    // This is impossible as the code runs within the same process in test.
                    throw new RuntimeException(e);
                }
            }
        }
    }

    @Override
    public List<CarPropertyValue<?>> getSetValues() {
        // Explicitly return the instance of this object rather than copying it such that test code
        // will have a chance to clear this list if needed.
        return mValuesSet;
    }

    /** Consists of property id and area */
    private static class PropKey {
        final int mPropId;
        final int mAreaId;

        private PropKey(int propId, int areaId) {
            this.mPropId = propId;
            this.mAreaId = areaId;
        }

        static PropKey of(int propId, int areaId) {
            return new PropKey(propId, areaId);
        }

        static PropKey of(CarPropertyValue carPropertyValue) {
            return of(carPropertyValue.getPropertyId(), carPropertyValue.getAreaId());
        }

        @Override

        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (!(o instanceof PropKey)) {
                return false;
            }
            PropKey propKey = (PropKey) o;
            return mPropId == propKey.mPropId && mAreaId == propKey.mAreaId;
        }

        @Override
        public int hashCode() {
            return Objects.hash(mPropId, mAreaId);
        }
    }

    private static class ListenerInfo {
        private final ICarPropertyEventListener mListener;

        ListenerInfo(ICarPropertyEventListener listener) {
            this.mListener = listener;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (!(o instanceof ListenerInfo)) {
                return false;
            }
            ListenerInfo that = (ListenerInfo) o;
            return Objects.equals(mListener, that.mListener);
        }

        @Override
        public int hashCode() {
            return Objects.hash(mListener);
        }
    }

    private static Class<?> getPropertyType(int propId) {
        int type = propId & VehiclePropertyType.MASK;
        switch (type) {
            case VehiclePropertyType.BOOLEAN:
                return Boolean.class;
            case VehiclePropertyType.FLOAT:
                return Float.class;
            case VehiclePropertyType.INT32:
                return Integer.class;
            case VehiclePropertyType.INT64:
                return Long.class;
            case VehiclePropertyType.FLOAT_VEC:
                return Float[].class;
            case VehiclePropertyType.INT32_VEC:
                return Integer[].class;
            case VehiclePropertyType.INT64_VEC:
                return Long[].class;
            case VehiclePropertyType.STRING:
                return String.class;
            case VehiclePropertyType.BYTES:
                return byte[].class;
            case VehiclePropertyType.MIXED:
                return Object.class;
            default:
                throw new IllegalArgumentException("Unexpected type: " + toHexString(type));
        }
    }

    private static int getVehicleAreaType(int propId) {
        int halArea = propId & VehicleArea.MASK;
        switch (halArea) {
            case VehicleArea.GLOBAL:
                return VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL;
            case VehicleArea.SEAT:
                return VehicleAreaType.VEHICLE_AREA_TYPE_SEAT;
            case VehicleArea.DOOR:
                return VehicleAreaType.VEHICLE_AREA_TYPE_DOOR;
            case VehicleArea.WINDOW:
                return VehicleAreaType.VEHICLE_AREA_TYPE_WINDOW;
            case VehicleArea.MIRROR:
                return VehicleAreaType.VEHICLE_AREA_TYPE_MIRROR;
            case VehicleArea.WHEEL:
                return VehicleAreaType.VEHICLE_AREA_TYPE_WHEEL;
            default:
                throw new RuntimeException("Unsupported area type " + halArea);
        }
    }

    /** Copy from VHAL generated file VehicleArea.java */
    private static final class VehicleArea {
        static final int GLOBAL = 16777216 /* 0x01000000 */;
        static final int WINDOW = 50331648 /* 0x03000000 */;
        static final int MIRROR = 67108864 /* 0x04000000 */;
        static final int SEAT = 83886080 /* 0x05000000 */;
        static final int DOOR = 100663296 /* 0x06000000 */;
        static final int WHEEL = 117440512 /* 0x07000000 */;
        static final int MASK = 251658240 /* 0x0f000000 */;
    }
}
