/*
 * Copyright 2016 The Chromium Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
package io.flutter.inspections;

import com.intellij.execution.ExecutionException;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.ui.EditorNotificationPanel;
import com.intellij.ui.EditorNotifications;
import com.jetbrains.lang.dart.DartFileType;
import com.jetbrains.lang.dart.DartLanguage;
import io.flutter.FlutterBundle;
import io.flutter.module.FlutterModuleType;
import io.flutter.sdk.FlutterSdk;
import io.flutter.sdk.FlutterSdkService;
import io.flutter.settings.FlutterSettings;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class WrongDartSdkConfigurationNotificationProvider extends EditorNotifications.Provider<EditorNotificationPanel>
  implements DumbAware {
  private static final Key<EditorNotificationPanel> KEY = Key.create("Setup Dart SDK");

  private final Project project;

  public WrongDartSdkConfigurationNotificationProvider(@NotNull Project project, @NotNull EditorNotifications notifications) {
    this.project = project;
  }

  @Nullable
  private static EditorNotificationPanel createWrongSdkPanel(@NotNull Project project, @Nullable Module module) {
    if (module == null) return null;

    final FlutterSettings settings = FlutterSettings.getInstance(project);
    if (settings == null || settings.ignoreMismatchedDartSdks()) return null;

    EditorNotificationPanel panel = new EditorNotificationPanel();
    panel.setText(FlutterBundle.message("flutter.wrong.dart.sdk.warning"));
    panel.createActionLabel(FlutterBundle.message("dart.sdk.configuration.action.label"),
                            () -> FlutterSdkService.getInstance(project).configureDartSdk(module));
    panel.createActionLabel("Dismiss", () -> {
      settings.setIgnoreMismatchedDartSdks(true);
      panel.setVisible(false);
    });

    return panel;
  }

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

  @Override
  public EditorNotificationPanel createNotificationPanel(@NotNull VirtualFile file, @NotNull FileEditor fileEditor) {
    if (file.getFileType() != DartFileType.INSTANCE) return null;

    PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
    if (psiFile == null) return null;

    if (psiFile.getLanguage() != DartLanguage.INSTANCE) return null;

    Module module = ModuleUtilCore.findModuleForPsiElement(psiFile);
    if (module == null) return null;

    if (!ModuleType.is(module, FlutterModuleType.getInstance())) return null;

    try {
      final FlutterSdk sdk = FlutterSdk.getFlutterSdk(project);
      if (sdk == null) {
        return createNoSdkPanel();
      }
      final String flutterDartSdkPath = sdk.getDartSdkPath();
      final String dartSdkPath = sdk.getHomePath();
      if (!StringUtil.equals(flutterDartSdkPath, dartSdkPath)) {
        return createWrongSdkPanel(project, module);
      }
    }
    catch (ExecutionException e) {
      return createNoSdkPanel();
    }

    return null;
  }

  private static EditorNotificationPanel createNoSdkPanel() {
    //TODO(pq): add panel for unconfigured Flutter SDK.
    return null;
  }
}

@@ -248,16 +248,63 @@
 eption;%0A
+import com.intellij.openapi.diagnostic.Logger;%0A
 import c
@@ -963,16 +963,60 @@
 nguage;%0A
+import com.jetbrains.lang.dart.sdk.DartSdk;%0A
 import i
@@ -1509,23 +1509,150 @@
 te(%22
-Setup Dart SDK%22
+FlutterWrongDartSdkNotification%22);%0A%0A  private static final Logger LOG = Logger.getInstance(WrongDartSdkConfigurationNotificationProvider.class
 );%0A%0A
@@ -1768,52 +1768,8 @@
 ject
-, @NotNull EditorNotifications notifications
 ) %7B%0A
@@ -3300,17 +3300,24 @@
 tterSdk 
-s
+flutterS
 dk = Flu
@@ -3358,17 +3358,24 @@
     if (
-s
+flutterS
 dk == nu
@@ -3395,32 +3395,39 @@
  return createNo
+Flutter
 SdkPanel();%0A    
@@ -3426,24 +3426,212 @@
 ();%0A      %7D%0A
+%0A      DartSdk dartSdk = DartSdk.getDartSdk(project);%0A      if (dartSdk == null) %7B%0A        // TODO(devoncarew): Recommend to set up with Flutter's dart sdk.%0A%0A        return null;%0A      %7D%0A%0A
       final 
@@ -3654,25 +3654,32 @@
 rtSdkPath = 
-s
+flutterS
 dk.getDartSd
@@ -3720,17 +3720,21 @@
 kPath = 
-s
+dartS
 dk.getHo
@@ -3920,32 +3920,19 @@
     
-return createNoSdkPanel(
+LOG.error(e
 );%0A 
@@ -4008,16 +4008,23 @@
 createNo
+Flutter
 SdkPanel
@@ -4034,16 +4034,17 @@
 %7B%0A    //
+ 
 TODO(pq)
@@ -4085,16 +4085,17 @@
 er SDK.%0A
+%0A
     retu

fix a flutter sdk toast message (#143)