/*
 * Copyright 2016 The Bazel Authors. All rights reserved.
 *
 * 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.google.idea.common.experiments;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListenableScheduledFuture;
import com.google.common.util.concurrent.ListeningScheduledExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.util.concurrency.AppExecutorUtil;
import com.intellij.util.io.HttpRequests;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.jetbrains.io.JsonReaderEx;

/**
 * A singleton class that retrieves the experiments from the experiments service</a>.
 *
 * <p>The first time {@link #getExperimentValues()} is called, fresh data will be retrieved in the
 * current thread. Thereafter, data will be retrieved every 5 minutes in a background thread. If
 * there is a failure retrieving data, new attempts will be made every minute.
 */
final class WebExperimentSyncer {

  private static final Logger logger = Logger.getInstance(WebExperimentSyncer.class);

  private static final String DEFAULT_EXPERIMENT_URL =
      "https://intellij-experiments.appspot.com/api/experiments/";
  private static final String EXPERIMENTS_URL_PROPERTY = "intellij.experiments.url";

  private static final int SUCESSFUL_DOWNLOAD_DELAY_MINUTES = 5;
  private static final int DOWNLOAD_FAILURE_DELAY_MINUTES = 1;

  private final File cacheFile;
  private final String pluginName;

  // null indicates no fetch attempt has been made. After the first attempt, this will always be a
  // (possibly empty) map.
  private Map<String, String> experimentValues = null;

  private final ListeningScheduledExecutorService executor =
      MoreExecutors.listeningDecorator(AppExecutorUtil.getAppScheduledExecutorService());

  WebExperimentSyncer(String pluginName) {
    this.pluginName = pluginName;
    cacheFile =
        Paths.get(PathManager.getSystemPath(), "blaze", pluginName + ".experiments.cache.dat")
            .toFile();
  }

  /**
   * Get the last-retrieved set of experiment values.
   *
   * <p>The first time this method is called, an attempt to retrieve the values will take place.
   * Thereafter, the values will be retrieved every five minutes on a background thread and this
   * method will return the most recent successfully retrieved values.
   */
  synchronized Map<String, String> getExperimentValues() {
    if (experimentValues == null) {
      initialize();
    }

    return experimentValues;
  }

  private synchronized void setExperimentValues(HashMap<String, String> experimentValues) {
    this.experimentValues = experimentValues;
    saveCache(experimentValues);
  }

  /** Fetch and process the experiments on the current thread. */
  void initialize() {
    experimentValues = loadCache();
    ListenableFuture<String> response = executor.submit(new WebExperimentsDownloader());
    response.addListener(
        new WebExperimentsResultProcessor(response), MoreExecutors.sameThreadExecutor());
  }

  private void scheduleNextRefresh(boolean refreshWasSuccessful) {
    int delayInMinutes =
        refreshWasSuccessful ? SUCESSFUL_DOWNLOAD_DELAY_MINUTES : DOWNLOAD_FAILURE_DELAY_MINUTES;
    ListenableScheduledFuture<String> refreshResults =
        executor.schedule(new WebExperimentsDownloader(), delayInMinutes, TimeUnit.MINUTES);
    refreshResults.addListener(
        new WebExperimentsResultProcessor(refreshResults), MoreExecutors.sameThreadExecutor());
  }

  private class WebExperimentsDownloader implements Callable<String> {

    @Override
    public String call() throws Exception {
      logger.debug("About to fetch experiments.");
      return HttpRequests.request(
              System.getProperty(EXPERIMENTS_URL_PROPERTY, DEFAULT_EXPERIMENT_URL) + pluginName)
          .readString(null /* progress indicator */);
    }
  }

  private class WebExperimentsResultProcessor implements Runnable {

    private final Future<String> resultFuture;

    private WebExperimentsResultProcessor(Future<String> resultFuture) {
      this.resultFuture = resultFuture;
    }

    @Override
    public void run() {
      logger.debug("Experiments fetched. Processing results.");
      try {
        HashMap<String, String> mapBuilder = Maps.newHashMap();
        String result = resultFuture.get();
        try (JsonReaderEx reader = new JsonReaderEx(result)) {
          reader.beginObject();
          while (reader.hasNext()) {
            String experimentName = reader.nextName();
            String experimentValue = reader.nextString();
            mapBuilder.put(experimentName, experimentValue);
          }
        }
        setExperimentValues(mapBuilder);

        logger.debug("Successfully fetched experiments: " + getExperimentValues());
        scheduleNextRefresh(true /* refreshWasSuccessful */);
      } catch (InterruptedException | ExecutionException | RuntimeException e) {
        logger.debug("Error fetching experiments", e);
        scheduleNextRefresh(false /* refreshWasSuccessful */);
      }
    }
  }

  private void saveCache(HashMap<String, String> experiments) {
    try {
      SerializationUtil.saveToDisk(cacheFile, experiments);
    } catch (IOException e) {
      logger.warn("Could not save experiments cache to disk: " + cacheFile);
    }
  }

  @SuppressWarnings("unchecked")
  private Map<String, String> loadCache() {
    try {
      Map<String, String> loaded = (Map<String, String>) SerializationUtil.loadFromDisk(cacheFile);
      return loaded != null ? loaded : ImmutableMap.of();
    } catch (IOException e) {
      // This is normal, we might be offline and have never loaded the cache.
      logger.info("Could not load experiments file: " + cacheFile);
    }
    return ImmutableMap.of();
  }
}
