/*
 * Copyright (c) 2014, the Dart project authors.
 * 
 * Licensed under the Eclipse Public License v1.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.eclipse.org/legal/epl-v10.html
 * 
 * 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.dart.tools.core.internal.analysis.model;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.dart.engine.error.ErrorCode;
import com.google.dart.server.AnalysisError;
import com.google.dart.server.AnalysisServer;
import com.google.dart.server.AnalysisService;
import com.google.dart.server.HighlightRegion;
import com.google.dart.server.NavigationRegion;
import com.google.dart.server.Occurrences;
import com.google.dart.server.Outline;
import com.google.dart.server.OverrideMember;
import com.google.dart.server.SearchResult;
import com.google.dart.tools.core.analysis.model.AnalysisServerData;
import com.google.dart.tools.core.analysis.model.AnalysisServerHighlightsListener;
import com.google.dart.tools.core.analysis.model.AnalysisServerOutlineListener;
import com.google.dart.tools.core.analysis.model.AnalysisServerOverridesListener;
import com.google.dart.tools.core.analysis.model.SearchResultsListener;

import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Instances of {@code AnalysisServerData} manage and provide access to analysis results reported by
 * {@link AnalysisServer}.
 * 
 * @coverage dart.tools.core.model
 */
public class AnalysisServerDataImpl implements AnalysisServerData {
  private final Map<String, Set<AnalysisServerHighlightsListener>> highlightsSubscriptions = Maps.newHashMap();
  private final Map<String, Set<AnalysisServerOutlineListener>> outlineSubscriptions = Maps.newHashMap();
  private final Map<String, Set<AnalysisServerOverridesListener>> overridesSubscriptions = Maps.newHashMap();
  private final Map<String, AnalysisError[]> errorData = Maps.newHashMap();
  private final Map<String, NavigationRegion[]> navigationData = Maps.newHashMap();
  private final Map<String, Occurrences[]> occurrencesData = Maps.newHashMap();
  private final Map<AnalysisService, List<String>> analysisSubscriptions = Maps.newHashMap();
  private final Map<String, SearchResultsListener> searchResultsListeners = Maps.newHashMap();
  private final Map<String, List<SearchResultsSet>> searchResultsData = Maps.newHashMap();
  // TODO(scheglov) restore or remove for the new API
//  private final Map<String, Set<ErrorCode>> fixableErrorCodesData = Maps.newHashMap();

  private AnalysisServer server;

  @Override
  public synchronized void addSearchResultsListener(String searchId, SearchResultsListener listener) {
    List<SearchResultsSet> resultsSets = searchResultsData.remove(searchId);
    boolean hasLast = false;
    if (resultsSets != null) {
      for (SearchResultsSet searchResultsSet : resultsSets) {
        listener.computedSearchResults(searchResultsSet.results, searchResultsSet.last);
        hasLast |= searchResultsSet.last;
      }
    }
    if (!hasLast) {
      searchResultsListeners.put(searchId, listener);
    }
  }

  @Override
  public AnalysisError[] getErrors(String file) {
    AnalysisError[] errors = errorData.get(file);
    if (errors == null) {
      return AnalysisError.NO_ERRORS;
    }
    return errors;
  }

  @Override
  public NavigationRegion[] getNavigation(String file) {
    NavigationRegion[] sourceRegions = navigationData.get(file);
    if (sourceRegions == null) {
      return NavigationRegion.EMPTY_ARRAY;
    }
    return sourceRegions;
  }

  @Override
  public Occurrences[] getOccurrences(String file) {
    Occurrences[] occurrencesArray = occurrencesData.get(file);
    if (occurrencesArray == null) {
      return Occurrences.EMPTY_ARRAY;
    }
    return occurrencesArray;
  }

  @Override
  public boolean isFixableErrorCode(String file, ErrorCode errorCode) {
    // TODO(scheglov) restore or remove for the new API
    return false;
//    Set<ErrorCode> fixableErrorCodes = fixableErrorCodesData.get(contextId);
//    if (fixableErrorCodes == null) {
//      return false;
//    }
//    return fixableErrorCodes.contains(errorCode);
  }

  @Override
  public synchronized void removeSearchResultsListener(String searchId,
      SearchResultsListener listener) {
    searchResultsData.remove(searchId);
    searchResultsListeners.remove(searchId);
  }

  /**
   * Sets the {@link AnalysisServer} to talk to.
   */
  public void setServer(AnalysisServer server) {
    this.server = server;
  }

  @Override
  public void subscribeHighlights(String file, AnalysisServerHighlightsListener listener) {
    Set<AnalysisServerHighlightsListener> subscriptions = highlightsSubscriptions.get(file);
    if (subscriptions == null) {
      subscriptions = Sets.newHashSet();
      highlightsSubscriptions.put(file, subscriptions);
    }
    if (subscriptions.add(listener)) {
      addAnalysisSubscription(AnalysisService.HIGHLIGHTS, file);
    }
  }

  @Override
  public void subscribeNavigation(String file) {
    addAnalysisSubscription(AnalysisService.NAVIGATION, file);
  }

  @Override
  public void subscribeOccurrences(String file) {
    addAnalysisSubscription(AnalysisService.OCCURRENCES, file);
  }

  @Override
  public void subscribeOutline(String file, AnalysisServerOutlineListener listener) {
    Set<AnalysisServerOutlineListener> subscriptions = outlineSubscriptions.get(file);
    if (subscriptions == null) {
      subscriptions = Sets.newHashSet();
      outlineSubscriptions.put(file, subscriptions);
    }
    if (subscriptions.add(listener)) {
      addAnalysisSubscription(AnalysisService.OUTLINE, file);
    }
  }

  @Override
  public void subscribeOverrides(String file, AnalysisServerOverridesListener listener) {
    Set<AnalysisServerOverridesListener> subscriptions = overridesSubscriptions.get(file);
    if (subscriptions == null) {
      subscriptions = Sets.newHashSet();
      overridesSubscriptions.put(file, subscriptions);
    }
    if (subscriptions.add(listener)) {
      addAnalysisSubscription(AnalysisService.OVERRIDES, file);
    }
  }

  @Override
  public void unsubscribeHighlights(String file, AnalysisServerHighlightsListener listener) {
    Set<AnalysisServerHighlightsListener> subscriptions = highlightsSubscriptions.get(file);
    if (subscriptions == null) {
      return;
    }
    if (subscriptions.remove(listener)) {
      if (subscriptions.isEmpty()) {
        removeAnalysisSubscription(AnalysisService.HIGHLIGHTS, file);
      }
    }
  }

  @Override
  public void unsubscribeNavigation(String file) {
    removeAnalysisSubscription(AnalysisService.NAVIGATION, file);
  }

  @Override
  public void unsubscribeOccurrences(String file) {
    removeAnalysisSubscription(AnalysisService.OCCURRENCES, file);
  }

  @Override
  public void unsubscribeOutline(String file, AnalysisServerOutlineListener listener) {
    Set<AnalysisServerOutlineListener> subscriptions = outlineSubscriptions.get(file);
    if (subscriptions == null) {
      return;
    }
    if (subscriptions.remove(listener)) {
      if (subscriptions.isEmpty()) {
        removeAnalysisSubscription(AnalysisService.OUTLINE, file);
      }
    }
  }

  @Override
  public void unsubscribeOverrides(String file, AnalysisServerOverridesListener listener) {
    Set<AnalysisServerOverridesListener> subscriptions = overridesSubscriptions.get(file);
    if (subscriptions == null) {
      return;
    }
    if (subscriptions.remove(listener)) {
      if (subscriptions.isEmpty()) {
        removeAnalysisSubscription(AnalysisService.OVERRIDES, file);
      }
    }
  }

  void internalComputedErrors(String file, AnalysisError[] errors) {
    errorData.put(file, errors);
  }

  void internalComputedHighlights(String file, HighlightRegion[] highlights) {
    Set<AnalysisServerHighlightsListener> subscriptions = highlightsSubscriptions.get(file);
    if (subscriptions == null) {
      return;
    }
    subscriptions = ImmutableSet.copyOf(subscriptions);
    for (AnalysisServerHighlightsListener listener : subscriptions) {
      listener.computedHighlights(file, highlights);
    }
  }

  void internalComputedNavigation(String file, NavigationRegion[] targets) {
    navigationData.put(file, targets);
  }

  void internalComputedOccurrences(String file, Occurrences[] occurrencesArray) {
    occurrencesData.put(file, occurrencesArray);
  }

  void internalComputedOutline(String file, Outline outline) {
    Set<AnalysisServerOutlineListener> subscriptions = outlineSubscriptions.get(file);
    if (subscriptions == null) {
      return;
    }
    subscriptions = ImmutableSet.copyOf(subscriptions);
    for (AnalysisServerOutlineListener listener : subscriptions) {
      listener.computedOutline(file, outline);
    }
  }

  void internalComputedOverrides(String file, OverrideMember[] overrides) {
    Set<AnalysisServerOverridesListener> subscriptions = overridesSubscriptions.get(file);
    if (subscriptions == null) {
      return;
    }
    subscriptions = ImmutableSet.copyOf(subscriptions);
    for (AnalysisServerOverridesListener listener : subscriptions) {
      listener.computedHighlights(file, overrides);
    }
  }

  synchronized void internalComputedSearchResults(String searchId, SearchResult[] results,
      boolean last) {
    SearchResultsListener listener = searchResultsListeners.get(searchId);
    if (listener != null) {
      if (last) {
        searchResultsListeners.remove(searchId);
      }
      listener.computedSearchResults(results, last);
    }
  }

  /**
   * Remembers the {@link ErrorCode} that may be fixed in the given context.
   */
  void internalSetFixableErrorCodes(String file, ErrorCode[] errorCodes) {
    // TODO(scheglov) restore or remove for the new API
//    fixableErrorCodesData.put(contextId, Sets.newHashSet(errorCodes));
  }

  /**
   * Adds the given file to the subscription list for the given {@link AnalysisService}.
   */
  private void addAnalysisSubscription(AnalysisService service, String file) {
    List<String> files = analysisSubscriptions.get(service);
    if (files == null) {
      files = Lists.newArrayList();
      analysisSubscriptions.put(service, files);
    }
    if (!files.contains(file)) {
      files.add(file);
      // TODO (jwren) re-enable after it is working in the java server again:
//      server.analysis_setSubscriptions(analysisSubscriptions);
    }
  }

  /**
   * Removes the given file from the subscription list for the given {@link AnalysisService}.
   */
  private void removeAnalysisSubscription(AnalysisService service, String file) {
    List<String> files = analysisSubscriptions.get(service);
    if (files == null) {
      return;
    }
    if (files.remove(file)) {
      if (files.isEmpty()) {
        analysisSubscriptions.remove(service);
      }
      // TODO (jwren) re-implement after this is working
//      server.analysis_setSubscriptions(analysisSubscriptions);
    }
  }
}
