// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.internal.statistic.libraryJar;

import com.intellij.internal.statistic.beans.UsageDescriptor;
import com.intellij.internal.statistic.eventLog.FeatureUsageData;
import com.intellij.internal.statistic.service.fus.collectors.ProjectUsagesCollector;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.JarUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.search.ProjectScope;
import java.util.HashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Set;
import java.util.jar.Attributes;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Andrey Cheptsov
 */
public class FUSLibraryJarUsagesCollector extends ProjectUsagesCollector {
  private static final String DIGIT_VERSION_PATTERN_PART = "(\\d+.\\d+|\\d+)";
  private static final Pattern JAR_FILE_NAME_PATTERN = Pattern.compile("[\\w|\\-|\\.]+-(" + DIGIT_VERSION_PATTERN_PART + "[\\w|\\.]*)jar");

  @NotNull
  @Override
  public Set<UsageDescriptor> getUsages(@NotNull Project project) {
    LibraryJarDescriptor[] descriptors = LibraryJarStatisticsService.getInstance().getTechnologyDescriptors();
    Set<UsageDescriptor> result = new HashSet<>(descriptors.length);

    ApplicationManager.getApplication().runReadAction(() -> {
      for (LibraryJarDescriptor descriptor : descriptors) {
        String className = descriptor.myClass;
        if (className == null) continue;

        PsiClass[] psiClasses = JavaPsiFacade.getInstance(project).findClasses(className, ProjectScope.getLibrariesScope(project));
        for (PsiClass psiClass : psiClasses) {
          VirtualFile jarFile = JarFileSystem.getInstance().getVirtualFileForJar(psiClass.getContainingFile().getVirtualFile());
          if (jarFile != null) {
            String version = getVersionByJarManifest(jarFile);
            if (version == null) version = getVersionByJarFileName(jarFile.getName());
            if (StringUtil.isNotEmpty(version)) {
              result.add(new UsageDescriptor(descriptor.myName, 1, new FeatureUsageData().addOS().addVersionByString(version)));
            }
          }
        }
      }
    });

    return result;
  }

  @Nullable
  private static String getVersionByJarManifest(@NotNull VirtualFile file) {
    return JarUtil.getJarAttribute(VfsUtilCore.virtualToIoFile(file), Attributes.Name.IMPLEMENTATION_VERSION);
  }

  @Nullable
  private static String getVersionByJarFileName(@NotNull String fileName) {
    Matcher fileNameMatcher = JAR_FILE_NAME_PATTERN.matcher(fileName);
    if (!fileNameMatcher.matches()) return null;

    return StringUtil.trimTrailing(fileNameMatcher.group(1), '.');
  }

  @NotNull
  @Override
  public String getGroupId() {
    return "javaLibraryJars";
  }
}
@@ -232,31 +232,27 @@
 c.beans.
-UsageDescriptor
+MetricEvent
 ;%0Aimport
@@ -856,34 +856,8 @@
 pe;%0A
-import java.util.HashSet;%0A
 impo
@@ -938,16 +938,42 @@
 lable;%0A%0A
+import java.util.HashSet;%0A
 import j
@@ -1451,36 +1451,181 @@
 ic S
-et%3CUsageDescriptor%3E getUsage
+tring getGroupId() %7B%0A    return %22javaLibraryJars%22;%0A  %7D%0A%0A  @Override%0A  public int getVersion() %7B%0A    return 2;%0A  %7D%0A%0A  @NotNull%0A  @Override%0A  public Set%3CMetricEvent%3E getMetric
 s(@N
@@ -1769,31 +1769,27 @@
     Set%3C
-UsageDescriptor
+MetricEvent
 %3E result
@@ -2597,60 +2597,37 @@
     
-result.add(new UsageDescriptor(descriptor.myName, 1,
+final FeatureUsageData data =
  new
@@ -2650,16 +2650,8 @@
 a().
-addOS().
 addV
@@ -2673,16 +2673,117 @@
 version)
+.addData(%22library%22, descriptor.myName);%0A              result.add(new MetricEvent(%22used.library%22, data
 ));%0A    
@@ -3269,16 +3269,16 @@
  null;%0A%0A
+
     retu
@@ -3343,95 +3343,6 @@
 %0A  %7D
-%0A%0A  @NotNull%0A  @Override%0A  public String getGroupId() %7B%0A    return %22javaLibraryJars%22;%0A  %7D
 %0A%7D

move java library name to event data in "javaLibraryJars" (FUS-516)