/*
 * Copyright (C) 2020 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.controls.cts;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;

import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.graphics.drawable.Icon;
import android.service.controls.Control;
import android.service.controls.ControlsProviderService;
import android.service.controls.DeviceTypes;
import android.service.controls.actions.BooleanAction;
import android.service.controls.actions.CommandAction;
import android.service.controls.actions.ControlAction;
import android.service.controls.actions.FloatAction;
import android.service.controls.actions.ModeAction;
import android.service.controls.templates.ControlButton;
import android.service.controls.templates.ControlTemplate;
import android.service.controls.templates.RangeTemplate;
import android.service.controls.templates.StatelessTemplate;
import android.service.controls.templates.TemperatureControlTemplate;
import android.service.controls.templates.ThumbnailTemplate;
import android.service.controls.templates.ToggleRangeTemplate;
import android.service.controls.templates.ToggleTemplate;

import androidx.test.InstrumentationRegistry;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Flow.Publisher;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
  * CTS Controls Service to send known controls for testing.
  */
public class CtsControlsService extends ControlsProviderService {

    private CtsControlsPublisher mUpdatePublisher;
    private final List<Control> mAllControls = new ArrayList<>();
    private final Map<String, Control> mControlsById = new HashMap<>();
    private final Context mContext;
    private final PendingIntent mPendingIntent;
    private ColorStateList mColorStateList;
    private Icon mIcon;

    public CtsControlsService() {
        mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
        mPendingIntent = PendingIntent.getActivity(mContext, 1,
                new Intent().setPackage(mContext.getPackageName()),
            PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
        mIcon = Icon.createWithResource(mContext, R.drawable.ic_device_unknown);
        mColorStateList = mContext.getResources().getColorStateList(R.color.custom_mower, null);

        mAllControls.add(buildLight(false /* isOn */, 0.0f /* intensity */));
        mAllControls.add(buildLock(false /* isLocked */));
        mAllControls.add(buildRoutine());
        mAllControls.add(buildThermostat(TemperatureControlTemplate.MODE_OFF));
        mAllControls.add(buildMower(false /* isStarted */));
        mAllControls.add(buildSwitch(false /* isOn */));
        mAllControls.add(buildGate(false /* isLocked */));
        mAllControls.add(buildCamera(true /* isActive */));

        for (Control c : mAllControls) {
            mControlsById.put(c.getControlId(), c);
        }
    }

    public Control buildLight(boolean isOn, float intensity) {
        RangeTemplate rt = new RangeTemplate("range", 0.0f, 100.0f, intensity, 1.0f, null);
        ControlTemplate template =
                new ToggleRangeTemplate("toggleRange", isOn, isOn ? "On" : "Off", rt);
        return new Control.StatefulBuilder("light", mPendingIntent)
            .setTitle("Light Title")
            .setSubtitle("Light Subtitle")
            .setStatus(Control.STATUS_OK)
            .setStatusText(isOn ? "On" : "Off")
            .setDeviceType(DeviceTypes.TYPE_LIGHT)
            .setStructure("Home")
            .setControlTemplate(template)
            .setAuthRequired(false)
            .build();
    }

    public Control buildSwitch(boolean isOn) {
        ControlButton button = new ControlButton(isOn, isOn ? "On" : "Off");
        ControlTemplate template = new ToggleTemplate("toggle", button);
        return new Control.StatefulBuilder("switch", mPendingIntent)
            .setTitle("Switch Title")
            .setSubtitle("Switch Subtitle")
            .setStatus(Control.STATUS_OK)
            .setStatusText(isOn ? "On" : "Off")
            .setDeviceType(DeviceTypes.TYPE_SWITCH)
            .setStructure("Home")
            .setControlTemplate(template)
            .build();
    }


    public Control buildMower(boolean isStarted) {
        String desc = isStarted ? "Started" : "Stopped";
        ControlButton button = new ControlButton(isStarted, desc);
        ControlTemplate template = new ToggleTemplate("toggle", button);
        return new Control.StatefulBuilder("mower", mPendingIntent)
            .setTitle("Mower Title")
            .setSubtitle("Mower Subtitle")
            .setStatus(Control.STATUS_OK)
            .setStatusText(desc)
            .setDeviceType(DeviceTypes.TYPE_MOWER)
            .setStructure("Vacation")
            .setZone("Outside")
            .setControlTemplate(template)
            .setCustomIcon(mIcon)
            .setCustomColor(mColorStateList)
            .build();
    }

    public Control buildLock(boolean isLocked) {
        String desc = isLocked ? "Locked" : "Unlocked";
        ControlButton button = new ControlButton(isLocked, desc);
        ControlTemplate template = new ToggleTemplate("toggle", button);
        return new Control.StatefulBuilder("lock", mPendingIntent)
            .setTitle("Lock Title")
            .setSubtitle("Lock Subtitle")
            .setStatus(Control.STATUS_OK)
            .setStatusText(desc)
            .setDeviceType(DeviceTypes.TYPE_LOCK)
            .setControlTemplate(template)
            .build();
    }

    public Control buildGate(boolean isLocked) {
        String desc = isLocked ? "Locked" : "Unlocked";
        ControlButton button = new ControlButton(isLocked, desc);
        ControlTemplate template = new ToggleTemplate("toggle", button);
        return new Control.StatefulBuilder("gate", mPendingIntent)
            .setTitle("Gate Title")
            .setSubtitle("Gate Subtitle")
            .setStatus(Control.STATUS_OK)
            .setStatusText(desc)
            .setDeviceType(DeviceTypes.TYPE_GATE)
            .setControlTemplate(template)
            .setStructure("Other home")
            .build();
    }

    public Control buildThermostat(int mode) {
        ControlTemplate template = new TemperatureControlTemplate("temperature",
                    ControlTemplate.getNoTemplateObject(),
                    mode,
                    TemperatureControlTemplate.MODE_OFF,
                    TemperatureControlTemplate.FLAG_MODE_HEAT
                    | TemperatureControlTemplate.FLAG_MODE_COOL
                    | TemperatureControlTemplate.FLAG_MODE_OFF
                    | TemperatureControlTemplate.FLAG_MODE_ECO);

        return new Control.StatefulBuilder("thermostat", mPendingIntent)
            .setTitle("Thermostat Title")
            .setSubtitle("Thermostat Subtitle")
            .setStatus(Control.STATUS_OK)
            .setStatusText("Off")
            .setDeviceType(DeviceTypes.TYPE_THERMOSTAT)
            .setControlTemplate(template)
            .build();
    }

    public Control buildRoutine() {
        ControlTemplate template = new StatelessTemplate("stateless");
        return new Control.StatefulBuilder("routine", mPendingIntent)
            .setTitle("Routine Title")
            .setSubtitle("Routine Subtitle")
            .setStatus(Control.STATUS_OK)
            .setStatusText("Good Morning")
            .setDeviceType(DeviceTypes.TYPE_ROUTINE)
            .setControlTemplate(template)
            .build();
    }

    public Control buildCamera(boolean active) {
        String description = active ? "Live" : "Not live";
        ControlTemplate template = new ThumbnailTemplate("thumbnail", active, mIcon, description);
        return new Control.StatefulBuilder("camera", mPendingIntent)
                .setTitle("Camera Title")
                .setTitle("Camera Subtitle")
                .setStatus(Control.STATUS_OK)
                .setStatusText(description)
                .setDeviceType(DeviceTypes.TYPE_CAMERA)
                .setControlTemplate(template)
                .build();
    }

    @Override
    public Publisher<Control> createPublisherForAllAvailable() {
        return new CtsControlsPublisher(mAllControls.stream()
            .map(c -> new Control.StatelessBuilder(c).build())
            .collect(Collectors.toList()));
    }

    @Override
    public Publisher<Control> createPublisherForSuggested() {
        return new CtsControlsPublisher(mAllControls.stream()
            .map(c -> new Control.StatelessBuilder(c).build())
            .collect(Collectors.toList()));
    }

    @Override
    public Publisher<Control> createPublisherFor(List<String> controlIds) {
        mUpdatePublisher = new CtsControlsPublisher(null);

        for (String id : controlIds) {
            Control control = mControlsById.get(id);
            if (control == null) continue;

            mUpdatePublisher.onNext(control);
        }

        return mUpdatePublisher;
    }

    @Override
    public void performControlAction(String controlId, ControlAction action,
            Consumer<Integer> consumer) {
        Control c = mControlsById.get(controlId);
        if (c == null) return;

        // all values are hardcoded for this test
        assertEquals(action.getTemplateId(), "action");
        assertNotEquals(action, ControlAction.getErrorAction());

        Control.StatefulBuilder builder = controlToBuilder(c);

        // Modify the builder in order to update the Control to have predefined, verifiable behavior
        if (action instanceof BooleanAction) {
            BooleanAction b = (BooleanAction) action;

            if (c.getDeviceType() == DeviceTypes.TYPE_LIGHT) {
                RangeTemplate rt = new RangeTemplate("range",
                        0.0f /* minValue */,
                        100.0f /* maxValue */,
                        50.0f /* currentValue */,
                        1.0f /* step */, null);
                String desc = b.getNewState() ? "On" : "Off";

                builder.setStatusText(desc);
                builder.setControlTemplate(new ToggleRangeTemplate("toggleRange", b.getNewState(),
                        desc, rt));
            } else if (c.getDeviceType() == DeviceTypes.TYPE_ROUTINE) {
                builder.setStatusText("Running");
                builder.setControlTemplate(new StatelessTemplate("stateless"));
            } else if (c.getDeviceType() == DeviceTypes.TYPE_SWITCH) {
                String desc = b.getNewState() ? "On" : "Off";
                builder.setStatusText(desc);
                ControlButton button = new ControlButton(b.getNewState(), desc);
                builder.setControlTemplate(new ToggleTemplate("toggle", button));
            } else if (c.getDeviceType() == DeviceTypes.TYPE_LOCK) {
                String value = action.getChallengeValue();
                if (value != null && value.equals("1234")) {
                    String desc = b.getNewState() ? "Locked" : "Unlocked";
                    ControlButton button = new ControlButton(b.getNewState(), desc);
                    builder.setStatusText(desc);
                    builder.setControlTemplate(new ToggleTemplate("toggle", button));
                } else {
                    consumer.accept(ControlAction.RESPONSE_CHALLENGE_PIN);
                    return;
                }
            } else if (c.getDeviceType() == DeviceTypes.TYPE_GATE) {
                String value = action.getChallengeValue();
                if (value != null && value.equals("abc123")) {
                    String desc = b.getNewState() ? "Locked" : "Unlocked";
                    ControlButton button = new ControlButton(b.getNewState(), desc);
                    builder.setStatusText(desc);
                    builder.setControlTemplate(new ToggleTemplate("toggle", button));
                } else {
                    consumer.accept(ControlAction.RESPONSE_CHALLENGE_PASSPHRASE);
                    return;
                }
            } else if (c.getDeviceType() == DeviceTypes.TYPE_MOWER) {
                String value = action.getChallengeValue();
                if (value != null && value.equals("true")) {
                    String desc = b.getNewState() ? "Started" : "Stopped";
                    ControlButton button = new ControlButton(b.getNewState(), desc);
                    builder.setStatusText(desc);
                    builder.setControlTemplate(new ToggleTemplate("toggle", button));
                } else {
                    consumer.accept(ControlAction.RESPONSE_CHALLENGE_ACK);
                    return;
                }
            }
        } else if (action instanceof FloatAction) {
            FloatAction f = (FloatAction) action;
            if (c.getDeviceType() == DeviceTypes.TYPE_LIGHT) {
                RangeTemplate rt = new RangeTemplate("range", 0.0f, 100.0f, f.getNewValue(), 1.0f,
                        null);

                ToggleRangeTemplate trt = (ToggleRangeTemplate) c.getControlTemplate();
                String desc = trt.getActionDescription().toString();
                boolean state = trt.isChecked();

                builder.setStatusText(desc);
                builder.setControlTemplate(new ToggleRangeTemplate("toggleRange", state, desc, rt));
            }
        } else if (action instanceof ModeAction) {
            ModeAction m = (ModeAction) action;
            if (c.getDeviceType() == DeviceTypes.TYPE_THERMOSTAT) {
                ControlTemplate template = new TemperatureControlTemplate("temperature",
                        ControlTemplate.getNoTemplateObject(),
                        m.getNewMode(),
                        TemperatureControlTemplate.MODE_OFF,
                        TemperatureControlTemplate.FLAG_MODE_HEAT
                        | TemperatureControlTemplate.FLAG_MODE_COOL
                        | TemperatureControlTemplate.FLAG_MODE_OFF
                        | TemperatureControlTemplate.FLAG_MODE_ECO);

                builder.setControlTemplate(template);
            }
        } else if (action instanceof CommandAction) {
            builder.setControlTemplate(new StatelessTemplate("stateless"));
        }

        // Finally build and send the default OK status
        Control updatedControl = builder.build();
        mControlsById.put(controlId, updatedControl);
        mUpdatePublisher.onNext(updatedControl);
        consumer.accept(ControlAction.RESPONSE_OK);
    }

    private Control.StatefulBuilder controlToBuilder(Control c) {
        return new Control.StatefulBuilder(c.getControlId(), c.getAppIntent())
            .setTitle(c.getTitle())
            .setSubtitle(c.getSubtitle())
            .setStructure(c.getStructure())
            .setDeviceType(c.getDeviceType())
            .setZone(c.getZone())
            .setCustomIcon(c.getCustomIcon())
            .setCustomColor(c.getCustomColor())
            .setStatus(c.getStatus())
            .setStatusText(c.getStatusText())
            .setAuthRequired(c.isAuthRequired());
    }
}
