package com.haskforce;

import com.haskforce.jps.model.JpsHaskellModelSerializerExtension;
import com.haskforce.utils.ExecUtil;
import com.intellij.openapi.projectRoots.AdditionalDataConfigurable;
import com.intellij.openapi.projectRoots.SdkAdditionalData;
import com.intellij.openapi.projectRoots.SdkModel;
import com.intellij.openapi.projectRoots.SdkModificator;
import com.intellij.openapi.projectRoots.SdkType;
import com.intellij.openapi.util.SystemInfo;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.io.File;

public class HaskellSdkType extends SdkType {
    public HaskellSdkType() {
        super(JpsHaskellModelSerializerExtension.HASKELL_SDK_TYPE_ID);
    }

    @NotNull
    public static HaskellSdkType getInstance() {
        return SdkType.findInstance(HaskellSdkType.class);
    }

    @Override
    public Icon getIcon() {
        return HaskellIcons.FILE;
    }

    @Nullable
    @Override
    public AdditionalDataConfigurable createAdditionalDataConfigurable(SdkModel sdkModel,
                                                                       SdkModificator sdkModificator) {
        return null;
    }

    @Override
    public String getPresentableName() {
        return JpsHaskellModelSerializerExtension.HASKELL_SDK_TYPE_ID;
    }

    @Override
    public void saveAdditionalData(@NotNull SdkAdditionalData additionalData, @NotNull Element additional) {
    }

    @Override
    public boolean isValidSdkHome(String path) {
        return getVersionString(path) != null;
    }

    @Override
    public String suggestSdkName(String currentSdkName, String sdkHome) {
        return "GHC";
    }

    @Nullable
    @Override
    public String getVersionString(@NotNull final String sdkHome) {
        File ghc = getExecutable(sdkHome);
        if (ghc.canExecute()) {
            return ExecUtil.exec(String.format("\"%s\" --numeric-version", ghc.getPath()));
        }
        return null;
    }

    @Nullable
    @Override
    public String suggestHomePath() {
        return SystemInfo.isWindows ? suggestHomePathForWindows() : suggestHomePathForUNIX();
    }

    @Nullable
    public static String suggestHomePathForWindows() {
        final String ghcPath = ExecUtil.exec("where ghc.exe");
        if (ghcPath != null) {
            File ghc = new File(ghcPath);
            if (ghc.canExecute()) {
                return ghc.getParent();
            }
        }
        return null;
    }

    @Nullable
    public static String suggestHomePathForUNIX() {
        return ExecUtil.run("ghc --print-libdir");
    }

    @NotNull
    public static File getExecutable(@NotNull final String path) {
        return new File(path, SystemInfo.isWindows ? "ghc.exe" : "ghc");
    }
}

@@ -1783,25 +1783,16 @@
 nString(
-@NotNull 
 final St
@@ -1799,32 +1799,98 @@
 ring sdkHome) %7B%0A
+        if (sdkHome == null) %7B%0A            return null;%0A        %7D%0A
         File ghc
@@ -1980,33 +1980,28 @@
 til.
-exec(String.format(%22%5C%22%25s%5C
+run(ghc.getPath() + 
 %22 --
@@ -2020,24 +2020,8 @@
 ion%22
-, ghc.getPath())
 );%0A 
@@ -2135,98 +2135,49 @@
     
-return SystemInfo.isWindows ? suggestHomePathForWindows() : suggestHomePathForUNIX
+String libPath = suggestGhcLibDir
 ();%0A    
 %7D%0A%0A 
@@ -2176,196 +2176,84 @@
     
-%7D%0A%0A
     
-@Nullable%0A    public static String suggestHomePathForWindows() %7B%0A        final String ghcPath = ExecUtil.exec(%22where ghc.exe%22);%0A        if (ghcPath != null) %7B%0A            File ghc =
+if (libPath == null) %7B%0A            return null;%0A        %7D%0A        return
  new
@@ -2262,145 +2262,144 @@
 ile(
-ghc
+lib
 Path)
-;%0A            if (ghc.canExecute()) %7B%0A                return ghc.getParent();%0A            %7D%0A        %7D%0A        return null;
+.getParentFile().getParent();%0A    %7D%0A%0A    /**%0A     * Returns the value of ghc --print-libdir if ghc is available in PATH.
 %0A    
-%7D%0A
+ */
 %0A   
@@ -2445,165 +2445,509 @@
 gest
-HomePathForUNIX() %7B%0A        return ExecUtil.run(%22ghc --print-libdir%22);%0A    %7D%0A%0A    @NotNull%0A    public static File getExecutable(@NotNull final String path) %7B
+GhcLibDir() %7B%0A        // Try running whatever GHC we have in $PATH.%0A        return ExecUtil.run(%22ghc --print-libdir%22);%0A    %7D%0A%0A    /**%0A     * Best effort at locating GHC according to given path.%0A     */%0A    @NotNull%0A    public static File getExecutable(@NotNull final String path) %7B%0A        // We might get called with /usr/local/bin, or the true SDK%0A        // path. The goal is to run ghc at this stage, so adapt to whatever.%0A        String extra = path.endsWith(%22bin%22) ? %22%22 : File.separator + %22bin%22;
 %0A   
@@ -2971,16 +2971,24 @@
 ile(path
+ + extra
 , System

Rework the SDK autodetection logic to prevent the broken SDK message.