/*
 * Copyright 2000-2012 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.internal.statistic.updater;

import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationListener;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationInfo;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.application.PermanentInstallationID;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.project.ProjectManagerListener;
import com.intellij.util.concurrency.AppExecutorUtil;
import consulo.external.api.StatisticsBean;
import consulo.ide.webService.WebServiceApi;
import consulo.ide.webService.WebServiceApiSender;
import consulo.ide.webService.statistics.SendStatisticsUtil;
import consulo.logging.Logger;
import consulo.ui.UIAccess;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.io.IOException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

@Singleton
public class StatisticsSendManager {
  private static final Logger LOG = Logger.getInstance(StatisticsSendManager.class);

  private static final int DELAY_IN_MIN = 10;

  private final UsageStatisticsPersistenceComponent myUsageStatisticsComponent;

  private Future<?> myFuture;

  @Inject
  private StatisticsSendManager(Application application, UsageStatisticsPersistenceComponent usageStatisticsComponent) {
    myUsageStatisticsComponent = usageStatisticsComponent;

    application.getMessageBus().connect().subscribe(ProjectManager.TOPIC, new ProjectManagerListener() {
      @Override
      public void projectOpened(@Nonnull Project project, @Nonnull UIAccess uiAccess) {
        runStatisticsService();
      }
    });
  }

  public void sheduleRunIfStarted() {
    if (myFuture != null) {
      myFuture.cancel(false);
      myFuture = null;

      runStatisticsService();
    }
  }

  private void runStatisticsService() {
    if(!myUsageStatisticsComponent.isAllowed()) {
      if (myFuture != null) {
        myFuture.cancel(false);
        myFuture = null;
      }
      return;
    }

    if (myFuture != null) {
      return;
    }

    long oneDayAfterStart = System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1);

    // one day after installation
    if(oneDayAfterStart > PermanentInstallationID.date()) {
      return;
    }

    if (myUsageStatisticsComponent.isTimeToSend()) {
      runWithDelay();
    }
  }

  private void runWithDelay() {
    myFuture = AppExecutorUtil.getAppScheduledExecutorService().schedule((Runnable)() -> {
      try {
        sendNow();
      }
      finally {
        myFuture = null;
      }
    }, DELAY_IN_MIN, TimeUnit.MINUTES);
  }

  public void sendNow() {
    StatisticsBean bean = SendStatisticsUtil.getBean();

    if (bean.groups.length == 0) {
      return;
    }

    try {
      WebServiceApiSender.doPost(WebServiceApi.STATISTICS_API, "push", bean);
    }
    catch (IOException e) {
      LOG.warn(e);
    }
  }

  // FIXME [VISTALL] at current moment we not show this notification
  public Notification createNotification(@Nonnull final String groupDisplayId, @Nullable NotificationListener listener) {
    final String fullProductName = ApplicationNamesInfo.getInstance().getFullProductName();
    final String companyName = ApplicationInfo.getInstance().getCompanyName();

    String text = "<html>Please click <a href='allow'>I agree</a> if you want to help make " +
                  fullProductName +
                  " better or <a href='decline'>I don't agree</a> otherwise. <a href='settings'>more...</a></html>";

    String title = "Help improve " + fullProductName + " by sending anonymous usage statistics to " + companyName;

    return new Notification(groupDisplayId, title, text, NotificationType.INFORMATION, listener);
  }
}

@@ -1329,24 +1329,60 @@
 ecutorUtil;%0A
+import consulo.disposer.Disposable;%0A
 import consu
@@ -1413,16 +1413,16 @@
 csBean;%0A
-
 import c
@@ -1905,16 +1905,38 @@
 Manager 
+implements Disposable 
 %7B%0A  priv
@@ -2619,32 +2619,162 @@
  %7D%0A    %7D);%0A  %7D%0A%0A
+  @Override%0A  public void dispose() %7B%0A    if (myFuture != null) %7B%0A      myFuture.cancel(false);%0A      myFuture = null;%0A    %7D%0A  %7D%0A%0A
   public void sh
@@ -3590,24 +3590,24 @@
       try %7B%0A
-
         send
@@ -3612,16 +3612,93 @@
 ndNow();
+%0A%0A        myUsageStatisticsComponent.setSentTime(System.currentTimeMillis());
 %0A      %7D

add dispose, also update sent time after data sent