/*
 * 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 static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.service.controls.Control;
import android.service.controls.ControlsProviderService;
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.ControlTemplate;
import android.service.controls.templates.RangeTemplate;
import android.service.controls.templates.TemperatureControlTemplate;
import android.service.controls.templates.ToggleRangeTemplate;
import android.service.controls.templates.ToggleTemplate;
import android.test.mock.MockContext;

import androidx.test.runner.AndroidJUnit4;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Flow.Publisher;
import java.util.concurrent.Flow.Subscriber;
import java.util.concurrent.Flow.Subscription;
import java.util.function.Consumer;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(AndroidJUnit4.class)
public class CtsControlsServiceTest {

    private static final String ACTION_ADD_CONTROL = "android.service.controls.action.ADD_CONTROL";
    private static final String EXTRA_CONTROL = "android.service.controls.extra.CONTROL";

    private CtsControlsService mControlsService;

    @Before
    public void setUp() {
        mControlsService = new CtsControlsService();
    }

    @Test
    public void testLoadAllAvailable() {
        Publisher<Control> publisher = mControlsService.createPublisherForAllAvailable();
        List<Control> loadedControls = new ArrayList<>();
        subscribe(publisher, 10, loadedControls);

        List<Control> expectedControls = new ArrayList<>();
        expectedControls.add(new Control.StatelessBuilder(
                mControlsService.buildLight(false, 0.0f)).build());
        expectedControls.add(new Control.StatelessBuilder(
                mControlsService.buildLock(false)).build());
        expectedControls.add(new Control.StatelessBuilder(
                mControlsService.buildRoutine()).build());
        expectedControls.add(new Control.StatelessBuilder(mControlsService.buildThermostat(
                TemperatureControlTemplate.MODE_OFF)).build());
        expectedControls.add(new Control.StatelessBuilder(
                mControlsService.buildMower(false)).build());
        expectedControls.add(new Control.StatelessBuilder(
                mControlsService.buildSwitch(false)).build());
        expectedControls.add(new Control.StatelessBuilder(
                mControlsService.buildGate(false)).build());
        expectedControls.add(new Control.StatelessBuilder(
                mControlsService.buildCamera(true)).build());

        assertControlsList(loadedControls, expectedControls);
    }

    @Test
    public void testLoadSuggested() {
        Publisher<Control> publisher = mControlsService.createPublisherForSuggested();
        List<Control> loadedControls = new ArrayList<>();
        subscribe(publisher, 3, loadedControls);

        List<Control> expectedControls = new ArrayList<>();
        expectedControls.add(new Control.StatelessBuilder(
                mControlsService.buildLight(false, 0.0f)).build());
        expectedControls.add(new Control.StatelessBuilder(
                mControlsService.buildLock(false)).build());
        expectedControls.add(new Control.StatelessBuilder(
                mControlsService.buildRoutine()).build());

        assertControlsList(loadedControls, expectedControls);
    }

    @Test
    public void testPublisherForSingleControl() {
        List<String> idsToLoad = new ArrayList<>();
        idsToLoad.add("mower");

        Publisher<Control> publisher = mControlsService.createPublisherFor(idsToLoad);
        List<Control> loadedControls = new ArrayList<>();
        subscribe(publisher, 10, loadedControls);

        List<Control> expectedControls = new ArrayList<>();
        expectedControls.add(mControlsService.buildMower(false));

        assertControlsList(loadedControls, expectedControls);
    }

    @Test
    public void testPublisherForMultipleControls() {
        List<String> idsToLoad = new ArrayList<>();
        idsToLoad.add("lock");
        idsToLoad.add("light");

        Publisher<Control> publisher = mControlsService.createPublisherFor(idsToLoad);
        List<Control> loadedControls = new ArrayList<>();
        subscribe(publisher, 10, loadedControls);

        List<Control> expectedControls = new ArrayList<>();
        expectedControls.add(mControlsService.buildLock(false));
        expectedControls.add(mControlsService.buildLight(false, 0.0f));

        assertControlsList(loadedControls, expectedControls);
    }

    @Test
    public void testBooleanAction() {
        List<String> idsToLoad = new ArrayList<>();
        idsToLoad.add("switch");

        Publisher<Control> publisher = mControlsService.createPublisherFor(idsToLoad);
        List<Control> loadedControls = new ArrayList<>();
        subscribe(publisher, 10, loadedControls);

        BooleanAction action = new BooleanAction("action", true);
        assertEquals(action.getActionType(), ControlAction.TYPE_BOOLEAN);
        mControlsService.performControlAction("switch", action,
                assertConsumer(ControlAction.RESPONSE_OK));

        List<Control> expectedControls = new ArrayList<>();
        expectedControls.add(mControlsService.buildSwitch(false));
        expectedControls.add(mControlsService.buildSwitch(true));

        assertControlsList(loadedControls, expectedControls);
    }

    @Test
    public void testFloatAction() {
        List<String> idsToLoad = new ArrayList<>();
        idsToLoad.add("light");

        Publisher<Control> publisher = mControlsService.createPublisherFor(idsToLoad);
        List<Control> loadedControls = new ArrayList<>();
        subscribe(publisher, 10, loadedControls);

        mControlsService.performControlAction("light", new BooleanAction("action", true),
                assertConsumer(ControlAction.RESPONSE_OK));

        FloatAction action = new FloatAction("action", 80.0f);
        assertEquals(action.getActionType(), ControlAction.TYPE_FLOAT);
        mControlsService.performControlAction("light", action,
                assertConsumer(ControlAction.RESPONSE_OK));

        List<Control> expectedControls = new ArrayList<>();
        expectedControls.add(mControlsService.buildLight(false, 0.0f));
        expectedControls.add(mControlsService.buildLight(true, 50.0f));
        expectedControls.add(mControlsService.buildLight(true, 80.0f));

        assertControlsList(loadedControls, expectedControls);
    }

    @Test
    public void testCommandAction() {
        List<String> idsToLoad = new ArrayList<>();
        idsToLoad.add("routine");

        Publisher<Control> publisher = mControlsService.createPublisherFor(idsToLoad);
        List<Control> loadedControls = new ArrayList<>();
        subscribe(publisher, 10, loadedControls);

        CommandAction action = new CommandAction("action");
        assertEquals(action.getActionType(), ControlAction.TYPE_COMMAND);
        mControlsService.performControlAction("routine", action,
                assertConsumer(ControlAction.RESPONSE_OK));

        List<Control> expectedControls = new ArrayList<>();
        expectedControls.add(mControlsService.buildRoutine());
        expectedControls.add(mControlsService.buildRoutine());

        assertControlsList(loadedControls, expectedControls);
    }

    @Test
    public void testBooleanActionWithPinChallenge() {
        List<String> idsToLoad = new ArrayList<>();
        idsToLoad.add("lock");

        Publisher<Control> publisher = mControlsService.createPublisherFor(idsToLoad);
        List<Control> loadedControls = new ArrayList<>();
        subscribe(publisher, 10, loadedControls);

        mControlsService.performControlAction("lock", new BooleanAction("action", true),
                assertConsumer(ControlAction.RESPONSE_CHALLENGE_PIN));

        mControlsService.performControlAction("lock", new BooleanAction("action", true, "1234"),
                assertConsumer(ControlAction.RESPONSE_OK));

        List<Control> expectedControls = new ArrayList<>();
        expectedControls.add(mControlsService.buildLock(false));
        expectedControls.add(mControlsService.buildLock(true));

        assertControlsList(loadedControls, expectedControls);
    }

    @Test
    public void testBooleanActionWithPassphraseChallenge() {
        List<String> idsToLoad = new ArrayList<>();
        idsToLoad.add("gate");

        Publisher<Control> publisher = mControlsService.createPublisherFor(idsToLoad);
        List<Control> loadedControls = new ArrayList<>();
        subscribe(publisher, 10, loadedControls);

        mControlsService.performControlAction("gate", new BooleanAction("action", true),
                assertConsumer(ControlAction.RESPONSE_CHALLENGE_PASSPHRASE));

        mControlsService.performControlAction("gate", new BooleanAction("action", true, "abc123"),
                assertConsumer(ControlAction.RESPONSE_OK));

        List<Control> expectedControls = new ArrayList<>();
        expectedControls.add(mControlsService.buildGate(false));
        expectedControls.add(mControlsService.buildGate(true));

        assertControlsList(loadedControls, expectedControls);
    }

    @Test
    public void testBooleanActionWithAckChallenge() {
        List<String> idsToLoad = new ArrayList<>();
        idsToLoad.add("mower");

        Publisher<Control> publisher = mControlsService.createPublisherFor(idsToLoad);
        List<Control> loadedControls = new ArrayList<>();
        subscribe(publisher, 10, loadedControls);

        mControlsService.performControlAction("mower", new BooleanAction("action", true),
                assertConsumer(ControlAction.RESPONSE_CHALLENGE_ACK));

        mControlsService.performControlAction("mower", new BooleanAction("action", true, "true"),
                assertConsumer(ControlAction.RESPONSE_OK));

        List<Control> expectedControls = new ArrayList<>();
        expectedControls.add(mControlsService.buildMower(false));
        expectedControls.add(mControlsService.buildMower(true));

        assertControlsList(loadedControls, expectedControls);
    }

    @Test
    public void testModeAction() {
        List<String> idsToLoad = new ArrayList<>();
        idsToLoad.add("thermostat");

        Publisher<Control> publisher = mControlsService.createPublisherFor(idsToLoad);
        List<Control> loadedControls = new ArrayList<>();
        subscribe(publisher, 10, loadedControls);

        ModeAction action = new ModeAction("action", TemperatureControlTemplate.MODE_COOL);
        assertEquals(action.getActionType(), ControlAction.TYPE_MODE);
        mControlsService.performControlAction("thermostat", action,
                assertConsumer(ControlAction.RESPONSE_OK));

        List<Control> expectedControls = new ArrayList<>();
        expectedControls.add(mControlsService.buildThermostat(TemperatureControlTemplate.MODE_OFF));
        expectedControls.add(mControlsService.buildThermostat(
                TemperatureControlTemplate.MODE_COOL));

        assertControlsList(loadedControls, expectedControls);
    }

    @Test
    public void testRequestAddControl() {
        Resources res = mock(Resources.class);
        when(res.getString(anyInt())).thenReturn("");

        final ComponentName testComponent = new ComponentName("TestPkg", "TestClass");
        final Control control = new Control.StatelessBuilder(mControlsService.buildMower(false))
                .build();

        Context context = new MockContext() {
            public Resources getResources() {
                return res;
            }

            public void sendBroadcast(Intent intent, String receiverPermission) {
                assertEquals(intent.getAction(), ACTION_ADD_CONTROL);
                assertEquals((ComponentName) intent.getParcelableExtra(Intent.EXTRA_COMPONENT_NAME),
                        testComponent);
                assertEquals((Control) intent.getParcelableExtra(EXTRA_CONTROL), control);
                assertEquals(receiverPermission, "android.permission.BIND_CONTROLS");
            }
        };

        ControlsProviderService.requestAddControl(context, testComponent, control);
    }

    private Consumer<Integer> assertConsumer(int expectedStatus) {
        return (status) -> {
            ControlAction.isValidResponse(status);
            assertEquals((int) status, expectedStatus);
        };
    }

    private void subscribe(Publisher<Control> publisher, final int request,
            final List<Control> addToList) {
        publisher.subscribe(new Subscriber<Control>() {
                public void onSubscribe(Subscription s) {
                    s.request(request);
                }

                public void onNext(Control c) {
                    addToList.add(c);
                }

                public void onError(Throwable t) {
                    throw new IllegalStateException("onError should not be called here");
                }

                public void onComplete() {

                }
            });
    }

    private void assertControlsList(List<Control> actualControls, List<Control> expectedControls) {
        assertEquals(actualControls.size(), expectedControls.size());

        for (int i = 0; i < actualControls.size(); i++) {
            assertControlEquals(actualControls.get(i), expectedControls.get(i));
        }
    }

    private void assertControlEquals(Control c1, Control c2) {
        assertEquals(c1.getTitle(), c2.getTitle());
        assertEquals(c1.getSubtitle(), c2.getSubtitle());
        assertEquals(c1.getStructure(), c2.getStructure());
        assertEquals(c1.getZone(), c2.getZone());
        assertEquals(c1.getDeviceType(), c2.getDeviceType());
        assertEquals(c1.getStatus(), c2.getStatus());
        assertEquals(c1.getControlId(), c2.getControlId());
        assertEquals(c1.getCustomIcon(), c2.getCustomIcon());
        assertEquals(c1.getCustomColor(), c2.getCustomColor());
        assertEquals(c1.isAuthRequired(), c2.isAuthRequired());

        assertTemplateEquals(c1.getControlTemplate(), c2.getControlTemplate());
    }

    private void assertTemplateEquals(ControlTemplate ct1, ControlTemplate ct2) {
        if (ct1 == null) {
            assertNull(ct2);
            return;
        } else {
            assertNotNull(ct2);
        }

        assertNotEquals(ct1, ControlTemplate.getErrorTemplate());
        assertNotEquals(ct2, ControlTemplate.getErrorTemplate());
        assertEquals(ct1.getTemplateType(), ct2.getTemplateType());
        assertEquals(ct1.getTemplateId(), ct2.getTemplateId());

        switch (ct1.getTemplateType()) {
            case ControlTemplate.TYPE_TOGGLE:
                assertToggleTemplate((ToggleTemplate) ct1, (ToggleTemplate) ct2);
                break;
            case ControlTemplate.TYPE_RANGE:
                assertRangeTemplate((RangeTemplate) ct1, (RangeTemplate) ct2);
                break;
            case ControlTemplate.TYPE_TEMPERATURE:
                assertTemperatureControlTemplate((TemperatureControlTemplate) ct1,
                        (TemperatureControlTemplate) ct2);
                break;
            case ControlTemplate.TYPE_TOGGLE_RANGE:
                assertToggleRangeTemplate((ToggleRangeTemplate) ct1, (ToggleRangeTemplate) ct2);
                break;
        }
    }

    private void assertToggleTemplate(ToggleTemplate t1, ToggleTemplate t2) {
        assertEquals(t1.isChecked(), t2.isChecked());
        assertEquals(t1.getContentDescription(), t2.getContentDescription());
    }

    private void assertRangeTemplate(RangeTemplate t1, RangeTemplate t2) {
        assertEquals(t1.getMinValue(), t2.getMinValue(), 0.0f);
        assertEquals(t1.getMaxValue(), t2.getMaxValue(), 0.0f);
        assertEquals(t1.getCurrentValue(), t2.getCurrentValue(), 0.0f);
        assertEquals(t1.getStepValue(), t2.getStepValue(), 0.0f);
        assertEquals(t1.getFormatString(), t2.getFormatString());
    }

    private void assertTemperatureControlTemplate(TemperatureControlTemplate t1,
            TemperatureControlTemplate t2) {
        assertEquals(t1.getCurrentMode(), t2.getCurrentMode());
        assertEquals(t1.getCurrentActiveMode(), t2.getCurrentActiveMode());
        assertEquals(t1.getModes(), t2.getModes());
        assertTemplateEquals(t1.getTemplate(), t2.getTemplate());
    }

    private void assertToggleRangeTemplate(ToggleRangeTemplate t1, ToggleRangeTemplate t2) {
        assertEquals(t1.isChecked(), t2.isChecked());
        assertEquals(t1.getActionDescription(), t2.getActionDescription());
        assertRangeTemplate(t1.getRange(), t2.getRange());
    }
}
