/*
 * 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.systemui;

import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

import android.os.Looper;

import androidx.test.filters.SmallTest;

import com.android.systemui.Dependency.DependencyKey;
import com.android.systemui.statusbar.policy.FlashlightController;

import org.junit.Assert;
import org.junit.Test;

import java.io.FileDescriptor;
import java.io.PrintWriter;

@SmallTest
public class DependencyTest extends SysuiTestCase {

    public static final DependencyKey<Dumpable> DUMPABLE = new DependencyKey<>("dumpable");
    public static final DependencyKey<ConfigurationChangedReceiver> CONFIGURATION_CHANGED_RECEIVER
            = new DependencyKey<>("config_changed_receiver");

    @Test
    public void testClassDependency() {
        FlashlightController f = mock(FlashlightController.class);
        mDependency.injectTestDependency(FlashlightController.class, f);
        Assert.assertEquals(f, Dependency.get(FlashlightController.class));
    }

    @Test
    public void testStringDependency() {
        Looper l = Looper.getMainLooper();
        mDependency.injectTestDependency(Dependency.BG_LOOPER, l);
        assertEquals(l, Dependency.get(Dependency.BG_LOOPER));
    }

    @Test
    public void testDump() {
        Dumpable d = mock(Dumpable.class);
        String[] args = new String[0];
        FileDescriptor fd = mock(FileDescriptor.class);
        mDependency.injectTestDependency(DUMPABLE, d);
        Dependency.get(DUMPABLE);
        mDependency.dump(fd, mock(PrintWriter.class), args);
        verify(d).dump(eq(fd), any(), eq(args));
    }

    @Test
    public void testConfigurationChanged() {
        ConfigurationChangedReceiver d = mock(ConfigurationChangedReceiver.class);
        mDependency.injectTestDependency(CONFIGURATION_CHANGED_RECEIVER, d);
        Dependency.get(CONFIGURATION_CHANGED_RECEIVER);
        mDependency.onConfigurationChanged(null);
        verify(d).onConfigurationChanged(eq(null));
    }

    @Test
    public void testInitDependency() {
        Dependency.clearDependencies();
        Dependency dependency = new Dependency();
        SystemUIFactory
                .getInstance().getRootComponent().createDependency().createSystemUI(dependency);
        dependency.start();
    }
}
