/*
 * Copyright 2016 The Bazel Authors. All rights reserved.
 *
 * 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.google.idea.blaze.android.project;

import static com.google.common.truth.Truth.THROW_ASSERTION_ERROR;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;

import com.android.tools.idea.project.FeatureEnableService;
import com.google.common.collect.ImmutableList;
import com.google.idea.blaze.android.settings.BlazeAndroidUserSettings;
import com.google.idea.blaze.base.BlazeTestCase;
import com.google.idea.blaze.base.logging.EventLogger;
import com.google.idea.blaze.base.model.BlazeProjectData;
import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
import com.google.idea.blaze.base.settings.BlazeImportSettings;
import com.google.idea.blaze.base.settings.BlazeImportSettingsManager;
import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
import com.google.idea.common.experiments.ExperimentService;
import com.intellij.openapi.extensions.ExtensionPoint;
import com.intellij.openapi.extensions.ExtensionPointName;
import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Test cases for {@link BlazeFeatureEnableService}. */
@RunWith(JUnit4.class)
public class BlazeFeatureEnabledServiceTest extends BlazeTestCase {
  private MockExperimentService experimentService;
  private BlazeAndroidUserSettings userSettings;
  private MockBlazeProjectDataManager projectDataManager;
  private FeatureEnableService featureEnableService;

  @Override
  protected void initTest(
      @NotNull Container applicationServices, @NotNull Container projectServices) {
    super.initTest(applicationServices, projectServices);
    experimentService = new MockExperimentService();
    applicationServices.register(ExperimentService.class, experimentService);

    userSettings = new BlazeAndroidUserSettings();
    applicationServices.register(BlazeAndroidUserSettings.class, userSettings);

    projectDataManager = new MockBlazeProjectDataManager();
    projectServices.register(BlazeProjectDataManager.class, projectDataManager);

    BlazeImportSettingsManager importSettingsManager = new BlazeImportSettingsManager();
    importSettingsManager.setImportSettings(
        new BlazeImportSettings("", "", "", "", BuildSystem.Blaze));
    projectServices.register(BlazeImportSettingsManager.class, importSettingsManager);

    registerExtensionPoint(
        ExtensionPointName.create("com.google.idea.blaze.EventLogger"), EventLogger.class);
    ExtensionPoint<FeatureEnableService> extensionPoint =
        registerExtensionPoint(
            ExtensionPointName.create("com.android.project.featureEnableService"),
            FeatureEnableService.class);
    extensionPoint.registerExtension(new BlazeFeatureEnableService());

    featureEnableService = FeatureEnableService.getInstance(project);
  }

  @Test
  public void testIsBlazeFeatureEnableService() {
    assertThat(featureEnableService).isInstanceOf(BlazeFeatureEnableService.class);
  }

  @Test
  public void testIsNotBlazeFeatureEnableService() {
    BlazeImportSettingsManager.getInstance(project).loadState(null);
    assertThat(FeatureEnableService.getInstance(project))
        .isNotInstanceOf(BlazeFeatureEnableService.class);
  }

  @Test
  public void testGetLayoutEditorEnabled() {
    for (boolean experimentEnabled : ImmutableList.of(true, false)) {
      for (boolean settingEnabled : ImmutableList.of(true, false)) {
        for (boolean projectDataReady : ImmutableList.of(true, false)) {
          userSettings.setUseLayoutEditor(settingEnabled);
          experimentService.setEnableLayoutEditor(experimentEnabled);
          projectDataManager.setBlazeProjectData(
              projectDataReady ? mock(BlazeProjectData.class) : null);
          assertThat(featureEnableService.isLayoutEditorEnabled(project))
              .isEqualTo(settingEnabled && experimentEnabled && projectDataReady);
        }
      }
    }
  }

  private static class MockBlazeProjectDataManager implements BlazeProjectDataManager {
    private BlazeProjectData blazeProjectData;

    public void setBlazeProjectData(BlazeProjectData blazeProjectData) {
      this.blazeProjectData = blazeProjectData;
    }

    @Nullable
    @Override
    public BlazeProjectData getBlazeProjectData() {
      return blazeProjectData;
    }
  }

  private static class MockExperimentService implements ExperimentService {
    private boolean enableLayoutEditor;

    public void setEnableLayoutEditor(boolean enableLayoutEditor) {
      this.enableLayoutEditor = enableLayoutEditor;
    }

    @Override
    public boolean getExperiment(String key, boolean defaultValue) {
      assertThat(key).isEqualTo("enable.layout.editor");
      return enableLayoutEditor;
    }

    @Nullable
    @Override
    public String getExperimentString(String key, @Nullable String defaultValue) {
      THROW_ASSERTION_ERROR.fail("Should not be called.");
      return null;
    }

    @Override
    public int getExperimentInt(String key, int defaultValue) {
      THROW_ASSERTION_ERROR.fail("Should not be called.");
      return 0;
    }

    @Override
    public void startExperimentScope() {}

    @Override
    public void endExperimentScope() {}
  }
}
