<commit_before>package de.plushnikov.intellij.plugin.activity;

import com.intellij.compiler.CompilerConfiguration;
import com.intellij.compiler.CompilerConfigurationImpl;
import com.intellij.notification.*;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.OrderEntry;
import com.intellij.openapi.startup.StartupActivity;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.wm.StatusBar;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiPackage;
import com.intellij.ui.awt.RelativePoint;
import de.plushnikov.intellij.plugin.LombokBundle;
import de.plushnikov.intellij.plugin.Version;
import de.plushnikov.intellij.plugin.settings.ProjectSettings;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.event.HyperlinkEvent;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Shows notifications about project setup issues, that make the plugin not working.
 *
 * @author <NAME>
 */
public class LombokProjectValidatorActivity implements StartupActivity {

  @Override
  public void runActivity(@NotNull Project project) {
    // If plugin is not enabled - no point to continue
    if (!ProjectSettings.isLombokEnabledInProject(project)) {
      return;
    }

    final boolean hasLombokLibrary = hasLombokLibrary(project);

    NotificationGroup group = NotificationGroup.findRegisteredGroup(Version.PLUGIN_NAME);
    if (group == null) {
      group = new NotificationGroup(Version.PLUGIN_NAME, NotificationDisplayType.BALLOON, true);
    }

    // If dependency is missing and missing dependency notification setting is enabled (defaults to disabled)
    if (!hasLombokLibrary && ProjectSettings.isEnabled(project, ProjectSettings.IS_MISSING_LOMBOK_CHECK_ENABLED, false)) {
      Notification notification = group.createNotification(LombokBundle.message("config.warn.dependency.missing.title"),
        LombokBundle.message("config.warn.dependency.missing.message", project.getName()),
        NotificationType.ERROR, NotificationListener.URL_OPENING_LISTENER);

      Notifications.Bus.notify(notification, project);
    }

    // If dependency is present and out of date notification setting is enabled (defaults to disabled)
    if (hasLombokLibrary && ProjectSettings.isEnabled(project, ProjectSettings.IS_LOMBOK_VERSION_CHECK_ENABLED, false)) {
      final ModuleManager moduleManager = ModuleManager.getInstance(project);
      for (Module module : moduleManager.getModules()) {
        String lombokVersion = parseLombokVersion(findLombokEntry(ModuleRootManager.getInstance(module)));

        if (null != lombokVersion && compareVersionString(lombokVersion, Version.LAST_LOMBOK_VERSION) < 0) {
          Notification notification = group.createNotification(LombokBundle.message("config.warn.dependency.outdated.title"),
            LombokBundle.message("config.warn.dependency.outdated.message", project.getName(), module.getName(), lombokVersion, Version.LAST_LOMBOK_VERSION),
            NotificationType.WARNING, NotificationListener.URL_OPENING_LISTENER);

          Notifications.Bus.notify(notification, project);
        }
      }
    }

    // Annotation Processing check
    boolean annotationProcessorsEnabled = hasAnnotationProcessorsEnabled(project);
    if (hasLombokLibrary && !annotationProcessorsEnabled &&
      ProjectSettings.isEnabled(project, ProjectSettings.IS_ANNOTATION_PROCESSING_CHECK_ENABLED, true)) {

      suggestEnableAnnotations(project, group);
    }
  }

  private void suggestEnableAnnotations(Project project, NotificationGroup group) {
    Notification notification = group.createNotification(LombokBundle.message("config.warn.annotation-processing.disabled.title"),
      LombokBundle.message("config.warn.annotation-processing.disabled.message", project.getName()),
      NotificationType.ERROR,
      (not, e) -> {
        if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
          enableAnnotations(project);
          not.expire();
        }
      });

    Notifications.Bus.notify(notification, project);
  }

  private void enableAnnotations(Project project) {
    getCompilerConfiguration(project).getDefaultProcessorProfile().setEnabled(true);

    StatusBar statusBar = WindowManager.getInstance().getStatusBar(project);
    JBPopupFactory.getInstance()
      .createHtmlTextBalloonBuilder(
        "Java annotation processing has been enabled",
        MessageType.INFO,
        null
      )
      .setFadeoutTime(3000)
      .createBalloon()
      .show(RelativePoint.getNorthEastOf(statusBar.getComponent()), Balloon.Position.atRight);
  }

  private CompilerConfigurationImpl getCompilerConfiguration(Project project) {
    return (CompilerConfigurationImpl) CompilerConfiguration.getInstance(project);
  }

  private boolean hasAnnotationProcessorsEnabled(Project project) {
    CompilerConfigurationImpl compilerConfiguration = getCompilerConfiguration(project);
    return compilerConfiguration.getDefaultProcessorProfile().isEnabled();
  }

  private boolean hasLombokLibrary(Project project) {
    PsiPackage lombokPackage;
    try {
      lombokPackage = JavaPsiFacade.getInstance(project).findPackage("lombok");
    } catch (ProcessCanceledException ex) {
      lombokPackage = null;
    }
    return lombokPackage != null;
  }

  @Nullable
  private OrderEntry findLombokEntry(@NotNull ModuleRootManager moduleRootManager) {<commit_msg>activate all compiler configurations for annotation processing<commit_after>package de.plushnikov.intellij.plugin.activity;

import com.intellij.compiler.CompilerConfiguration;
import com.intellij.compiler.CompilerConfigurationImpl;
import com.intellij.notification.*;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.OrderEntry;
import com.intellij.openapi.startup.StartupActivity;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.wm.StatusBar;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiPackage;
import com.intellij.ui.awt.RelativePoint;
import de.plushnikov.intellij.plugin.LombokBundle;
import de.plushnikov.intellij.plugin.Version;
import de.plushnikov.intellij.plugin.settings.ProjectSettings;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.model.java.compiler.AnnotationProcessingConfiguration;

import javax.swing.event.HyperlinkEvent;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Shows notifications about project setup issues, that make the plugin not working.
 *
 * @author <NAME>
 */
public class LombokProjectValidatorActivity implements StartupActivity {

  @Override
  public void runActivity(@NotNull Project project) {
    // If plugin is not enabled - no point to continue
    if (!ProjectSettings.isLombokEnabledInProject(project)) {
      return;
    }

    final boolean hasLombokLibrary = hasLombokLibrary(project);

    NotificationGroup group = NotificationGroup.findRegisteredGroup(Version.PLUGIN_NAME);
    if (group == null) {
      group = new NotificationGroup(Version.PLUGIN_NAME, NotificationDisplayType.BALLOON, true);
    }

    // If dependency is missing and missing dependency notification setting is enabled (defaults to disabled)
    if (!hasLombokLibrary && ProjectSettings.isEnabled(project, ProjectSettings.IS_MISSING_LOMBOK_CHECK_ENABLED, false)) {
      Notification notification = group.createNotification(LombokBundle.message("config.warn.dependency.missing.title"),
        LombokBundle.message("config.warn.dependency.missing.message", project.getName()),
        NotificationType.ERROR, NotificationListener.URL_OPENING_LISTENER);

      Notifications.Bus.notify(notification, project);
    }

    // If dependency is present and out of date notification setting is enabled (defaults to disabled)
    if (hasLombokLibrary && ProjectSettings.isEnabled(project, ProjectSettings.IS_LOMBOK_VERSION_CHECK_ENABLED, false)) {
      final ModuleManager moduleManager = ModuleManager.getInstance(project);
      for (Module module : moduleManager.getModules()) {
        String lombokVersion = parseLombokVersion(findLombokEntry(ModuleRootManager.getInstance(module)));

        if (null != lombokVersion && compareVersionString(lombokVersion, Version.LAST_LOMBOK_VERSION) < 0) {
          Notification notification = group.createNotification(LombokBundle.message("config.warn.dependency.outdated.title"),
            LombokBundle.message("config.warn.dependency.outdated.message", project.getName(), module.getName(), lombokVersion, Version.LAST_LOMBOK_VERSION),
            NotificationType.WARNING, NotificationListener.URL_OPENING_LISTENER);

          Notifications.Bus.notify(notification, project);
        }
      }
    }

    // Annotation Processing check
    boolean annotationProcessorsEnabled = hasAnnotationProcessorsEnabled(project);
    if (hasLombokLibrary && !annotationProcessorsEnabled &&
      ProjectSettings.isEnabled(project, ProjectSettings.IS_ANNOTATION_PROCESSING_CHECK_ENABLED, true)) {

      suggestEnableAnnotations(project, group);
    }
  }

  private void suggestEnableAnnotations(Project project, NotificationGroup group) {
    Notification notification = group.createNotification(LombokBundle.message("config.warn.annotation-processing.disabled.title"),
      LombokBundle.message("config.warn.annotation-processing.disabled.message", project.getName()),
      NotificationType.ERROR,
      (not, e) -> {
        if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
          enableAnnotations(project);
          not.expire();
        }
      });

    Notifications.Bus.notify(notification, project);
  }

  private void enableAnnotations(Project project) {
    CompilerConfigurationImpl compilerConfiguration = getCompilerConfiguration(project);
    compilerConfiguration.getDefaultProcessorProfile().setEnabled(true);
    compilerConfiguration.getModuleProcessorProfiles().forEach(pp -> pp.setEnabled(true));

    StatusBar statusBar = WindowManager.getInstance().getStatusBar(project);
    JBPopupFactory.getInstance()
      .createHtmlTextBalloonBuilder(
        "Java annotation processing has been enabled",
        MessageType.INFO,
        null
      )
      .setFadeoutTime(3000)
      .createBalloon()
      .show(RelativePoint.getNorthEastOf(statusBar.getComponent()), Balloon.Position.atRight);
  }

  private CompilerConfigurationImpl getCompilerConfiguration(Project project) {
    return (CompilerConfigurationImpl) CompilerConfiguration.getInstance(project);
  }

  private boolean hasAnnotationProcessorsEnabled(Project project) {
    CompilerConfigurationImpl compilerConfiguration = getCompilerConfiguration(project);
    return compilerConfiguration.getDefaultProcessorProfile().isEnabled() &&
      compilerConfiguration.getModuleProcessorProfiles().stream().anyMatch(AnnotationProcessingConfiguration::isEnabled);
  }

  private boolean hasLombokLibrary(Project project) {
    PsiPackage lombokPackage;
    try {
      lombokPackage = JavaPsiFacade.getInstance(project).findPackage("lombok");
    } catch (ProcessCanceledException ex) {
      lombokPackage = null;
    }
    return lombokPackage != null;
  }

  @Nullable
  private OrderEntry findLombokEntry(@NotNull ModuleRootManager moduleRootManager) {
{'fraction_non_alphanumeric': 0.09248745165802683, 'fraction_numerical': 0.0008228420966016622, 'mean_word_length': 4.9549240568348845, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1122145', 'n_tokens_mistral': 3349, 'n_tokens_neox': 3247, 'n_words': 576}