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

import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.provider.Settings.Global;
import android.support.v7.preference.PreferenceScreen;

import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.core.lifecycle.Lifecycle;

import java.util.ArrayList;
import java.util.List;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;

import static com.android.settings.notification.SettingPref.TYPE_GLOBAL;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Answers.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class SettingPrefControllerTest {

    @Mock
    private PreferenceScreen mScreen;
    @Mock
    private SoundSettings mSetting;
    @Mock
    private Activity mActivity;
    @Mock
    private ContentResolver mContentResolver;

    private Context mContext;
    private PreferenceControllerTestable mController;
    private SettingPref mPreference;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        mContext = spy(ShadowApplication.getInstance().getApplicationContext());
        when(mContext.getContentResolver()).thenReturn(mContentResolver);
        when(mSetting.getActivity()).thenReturn(mActivity);
        doReturn(mScreen).when(mSetting).getPreferenceScreen();
        mController = new PreferenceControllerTestable(mContext, mSetting, null);
        mPreference = mController.getPref();
    }

    @Test
    public void displayPreference_shouldInitPreference() {
        mController.displayPreference(mScreen);

        verify(mPreference).init(mSetting);
    }

    @Test
    public void isAvailable_shouldCallisApplicable() {
        mController.isAvailable();

        verify(mPreference).isApplicable(mContext);
    }

    @Test
    public void getPreferenceKey_shouldReturnPrefKey() {
        assertThat(mController.getPreferenceKey()).isEqualTo(mController.KEY_TEST);
    }

    @Test
    public void updateState_shouldUpdatePreference() {
        mController.updateState(null);

        verify(mPreference).update(mContext);
    }

    @Test
    public void onResume_shouldRegisterContentObserver() {
        mController.displayPreference(mScreen);
        mController.onResume();

        verify(mContentResolver).registerContentObserver(
            Global.getUriFor("Setting1"), false, mController.getObserver());
    }

    @Test
    public void onPause_shouldUnregisterContentObserver() {
        mController.displayPreference(mScreen);
        mController.onPause();

        verify(mContentResolver).unregisterContentObserver(mController.getObserver());
    }

    @Test
    public void onContentChange_shouldUpdatePreference() {
        mController.displayPreference(mScreen);
        mController.onResume();
        mController.getObserver().onChange(false, Global.getUriFor("Setting1"));

        verify(mPreference).update(mContext);
    }

    @Test
    public void updateNonIndexableKeys_applicable_shouldNotUpdate() {
        final List<String> keys = new ArrayList<>();

        mController.updateNonIndexableKeys(keys);

        assertThat(keys).isEmpty();
    }

    @Test
    public void updateNonIndexableKeys_notApplicable_shouldUpdate() {
        mController.setApplicable(false);
        final List<String> keys = new ArrayList<>();

        mController.updateNonIndexableKeys(keys);

        assertThat(keys).isNotEmpty();
    }

    private class PreferenceControllerTestable extends SettingPrefController {

        private static final String KEY_TEST = "key1";
        private boolean mApplicable = true;

        public PreferenceControllerTestable(Context context, SettingsPreferenceFragment parent,
            Lifecycle lifecycle) {
            super(context, parent, lifecycle);
            mPreference = spy(new SettingPref(
                TYPE_GLOBAL, KEY_TEST, "Setting1", 1) {
                @Override
                public boolean isApplicable(Context context) {
                    return mApplicable;
                }
            });
        }

        SettingPref getPref() {
            return mPreference;
        }

        PreferenceControllerTestable.SettingsObserver getObserver() {
            return mSettingsObserver;
        }

        void setApplicable(boolean applicable) {
            mApplicable = applicable;
        }

    }

}
