/*
 * Copyright 2000-2013 JetBrains s.r.o.
 *
 * 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.intellij.ide.plugins;

import com.google.gson.Gson;
import com.intellij.ide.IdeBundle;
import com.intellij.openapi.application.ex.ApplicationInfoEx;
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.util.SystemProperties;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.net.HttpConfigurable;
import consulo.ide.plugins.PluginJsonNode;
import consulo.ide.updateSettings.UpdateChannel;
import consulo.ide.updateSettings.impl.PlatformOrPluginUpdateChecker;
import consulo.ide.webService.WebServiceApi;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.GZIPInputStream;

/**
 * @author stathik
 * @since Mar 28, 2003
 */
public class RepositoryHelper {
  @NotNull
  public static String buildUrlForList(@NotNull UpdateChannel channel, @NotNull String platformVersion) {
    return WebServiceApi.REPOSITORY_API.buildUrl("list") + "?platformVersion=" + platformVersion + "&channel=" + channel;
  }

  @NotNull
  public static String buildUrlForDownload(@NotNull UpdateChannel channel, @NotNull String pluginId, @Nullable String platformVersion, boolean viaUpdate) {
    if (platformVersion == null) {
      platformVersion = ApplicationInfoImpl.getShadowInstance().getBuild().asString();
    }

    StringBuilder builder = new StringBuilder();
    builder.append(WebServiceApi.REPOSITORY_API.buildUrl("download"));
    builder.append("?platformVersion=");
    builder.append(platformVersion);
    builder.append("&channel=");
    builder.append(channel);
    builder.append("&pluginId=");
    builder.append(pluginId);
    if(SystemProperties.getBooleanProperty("consulo.repository.no.tracking", false)) {
      builder.append("&noTracking=true");
    }
    if(viaUpdate) {
      builder.append("&viaUpdate=true");
    }
    return builder.toString();
  }

  /**
   * Load & return only plugins from repository
   */
  @NotNull
  public static List<IdeaPluginDescriptor> loadOnlyPluginsFromRepository(@Nullable ProgressIndicator indicator, @NotNull UpdateChannel channel)
          throws Exception {
    List<IdeaPluginDescriptor> ideaPluginDescriptors = loadPluginsFromRepository(indicator, channel);
    return ContainerUtil.filter(ideaPluginDescriptors, it -> !PlatformOrPluginUpdateChecker.isPlatform(it.getPluginId()));
  }

  @NotNull
  public static List<IdeaPluginDescriptor> loadPluginsFromRepository(@Nullable ProgressIndicator indicator, @NotNull UpdateChannel channel) throws Exception {
    return loadPluginsFromRepository(indicator, channel, null);
  }

  @NotNull
  public static List<IdeaPluginDescriptor> loadPluginsFromRepository(@Nullable ProgressIndicator indicator,
                                                                     @NotNull UpdateChannel channel,
                                                                     @Nullable("if null used app build number") String buildNumber) throws Exception {
    if (buildNumber == null) {
      ApplicationInfoEx appInfo = ApplicationInfoImpl.getShadowInstance();
      buildNumber = appInfo.getBuild().asString();
    }

    String url = buildUrlForList(channel, buildNumber);

    if (indicator != null) {
      indicator.setText2(IdeBundle.message("progress.connecting.to.plugin.manager", WebServiceApi.REPOSITORY_API.buildUrl()));
    }

    HttpURLConnection connection = HttpConfigurable.getInstance().openHttpConnection(url);
    connection.setRequestProperty("Accept-Encoding", "gzip");

    if (indicator != null) {
      indicator.setText2(IdeBundle.message("progress.waiting.for.reply.from.plugin.manager", WebServiceApi.REPOSITORY_API.buildUrl()));
    }

    connection.connect();
    try {
      if (indicator != null) {
        indicator.checkCanceled();
      }

      String encoding = connection.getContentEncoding();
      InputStream is = connection.getInputStream();
      try {
        if ("gzip".equalsIgnoreCase(encoding)) {
          is = new GZIPInputStream(is);
        }

        if (indicator != null) {
          indicator.setText2(IdeBundle.message("progress.downloading.list.of.plugins"));
        }

        return readPluginsStream(is, indicator);
      }
      finally {
        is.close();
      }
    }
    finally {
      connection.disconnect();
    }
  }

  private static List<IdeaPluginDescriptor> readPluginsStream(InputStream is, ProgressIndicator indicator) throws Exception {
    ByteArrayOutputStream os = new ByteArrayOutputStream();
    try {
      byte[] buffer = new byte[1024];
      int size;
      while ((size = is.read(buffer)) > 0) {
        os.write(buffer, 0, size);
        if (indicator != null) {
          indicator.checkCanceled();
        }
      }
    }
    finally {
      os.close();
    }

    PluginJsonNode[] nodes =
            new Gson().fromJson(new InputStreamReader(new ByteArrayInputStream(os.toByteArray()), StandardCharsets.UTF_8), PluginJsonNode[].class);

    List<IdeaPluginDescriptor> pluginDescriptors = new ArrayList<>(nodes.length);
    for (PluginJsonNode jsonPlugin : nodes) {
      pluginDescriptors.add(new PluginNode(jsonPlugin));
    }
    return pluginDescriptors;
  }
}

@@ -2030,68 +2030,260 @@
 nel,
- @NotNull String pluginId, @Nullable String platformVersion,
+%0A                                           @NotNull String pluginId,%0A                                           @Nullable String platformVersion,%0A                                           boolean noTracking,%0A                                          
  boo
@@ -2753,23 +2753,59 @@
 ginId);%0A
+%0A
     if
-(
+ (!noTracking) %7B%0A      noTracking = 
 SystemPr
@@ -2872,16 +2872,43 @@
 , false)
+;%0A    %7D%0A%0A    if (noTracking
 ) %7B%0A    
@@ -2951,22 +2951,23 @@
 ;%0A    %7D%0A
-
     if
+ 
 (viaUpda

add no tracking parameter