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

import com.google.common.collect.Sets;
import com.google.idea.blaze.base.model.BlazeProjectData;
import com.google.idea.blaze.base.model.primitives.LanguageClass;
import com.google.idea.blaze.base.projectview.ProjectViewEdit;
import com.google.idea.blaze.base.projectview.section.ListSection;
import com.google.idea.blaze.base.projectview.section.sections.AdditionalLanguagesSection;
import com.google.idea.blaze.base.settings.BlazeUserSettings;
import com.google.idea.blaze.base.sync.BlazeSyncManager;
import com.google.idea.blaze.base.sync.BlazeSyncParams;
import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
import com.google.idea.blaze.base.sync.projectview.LanguageSupport;
import com.google.idea.blaze.base.sync.projectview.WorkspaceLanguageSettings;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.EditorNotificationPanel;
import com.intellij.ui.EditorNotifications;
import java.util.Set;
import javax.annotation.Nullable;

/**
 * Detects usage of files in supported but inactive languages, and offers to add them to the project
 * view.
 */
public class AdditionalLanguagesHelper
    extends EditorNotifications.Provider<EditorNotificationPanel> {

  private static final Key<EditorNotificationPanel> KEY = Key.create("add additional language");

  // avoid notifying more than once per project per language.
  private final Set<LanguageClass> notifiedLanguages = Sets.newHashSet();
  private final Project project;
  private final EditorNotifications notifications;

  public AdditionalLanguagesHelper(Project project, final EditorNotifications notifications) {
    this.project = project;
    this.notifications = notifications;

    for (LanguageClass langauge : LanguageClass.values()) {
      if (PropertiesComponent.getInstance(project).getBoolean(propertyKey(langauge))) {
        notifiedLanguages.add(langauge);
      }
    }
  }

  private void suppressNotifications(LanguageClass language) {
    PropertiesComponent.getInstance(project).setValue(propertyKey(language), true);
    notifiedLanguages.add(language);
    notifications.updateAllNotifications();
  }

  private static String propertyKey(LanguageClass language) {
    return "additional_languages_helper_suppressed_" + language.getName();
  }

  @Override
  public Key<EditorNotificationPanel> getKey() {
    return KEY;
  }

  @Nullable
  @Override
  public EditorNotificationPanel createNotificationPanel(VirtualFile file, FileEditor fileEditor) {
    String ext = file.getExtension();
    if (ext == null) {
      return null;
    }
    LanguageClass language = LanguageClass.fromExtension(ext);
    if (language == null || notifiedLanguages.contains(language)) {
      return null;
    }
    BlazeProjectData projectData =
        BlazeProjectDataManager.getInstance(project).getBlazeProjectData();
    if (projectData == null) {
      return null;
    }
    WorkspaceLanguageSettings settings = projectData.workspaceLanguageSettings;
    if (settings.isLanguageActive(language)) {
      return null;
    }
    if (!LanguageSupport.supportedLanguagesForWorkspaceType(settings.getWorkspaceType())
        .contains(language)) {
      return null;
    }

    String langName = language.getName();
    String message =
        String.format("Do you want to enable %s support in your project view file?", langName);

    EditorNotificationPanel panel = new EditorNotificationPanel();
    panel.setText(message);
    panel.createActionLabel(
        String.format("Enable %s support", langName),
        () -> enableLanguageSupport(project, language));
    panel.createActionLabel("Don't show again", () -> suppressNotifications(language));
    return panel;
  }

  private void enableLanguageSupport(Project project, LanguageClass language) {
    ProjectViewEdit edit =
        ProjectViewEdit.editLocalProjectView(
            project,
            builder -> {
              ListSection<LanguageClass> existingSection =
                  builder.getLast(AdditionalLanguagesSection.KEY);
              builder.replace(
                  existingSection,
                  ListSection.update(AdditionalLanguagesSection.KEY, existingSection)
                      .add(language));
              return true;
            });
    if (edit == null) {
      Messages.showErrorDialog(
          "Could not modify project view. Check for errors in your project view and try again",
          "Error");
      return;
    }
    edit.apply();

    suppressNotifications(language);

    BlazeSyncManager.getInstance(project)
        .requestProjectSync(
            new BlazeSyncParams.Builder("Sync", BlazeSyncParams.SyncMode.INCREMENTAL)
                .addProjectViewTargets(true)
                .addWorkingSet(BlazeUserSettings.getInstance().getExpandSyncToWorkingSet())
                .build());
  }
}
