// Copyright (C) 2013 The Android Open Source Project
//
// 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.gerrit.client.projects;

import com.google.gerrit.client.changes.ChangeApi;
import com.google.gerrit.client.changes.ChangeInfo;
import com.google.gerrit.client.ui.CommentLinkProcessor;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;

import java.util.LinkedHashMap;
import java.util.Map;

/** Cache of {@link ConfigInfo} objects by project name. */
public class ConfigInfoCache {
  private static final int PROJECT_LIMIT = 25;
  private static final int CHANGE_LIMIT = 100;
  private static final ConfigInfoCache instance =
      GWT.create(ConfigInfoCache.class);

  public static class Entry {
    private final ConfigInfo info;
    private CommentLinkProcessor commentLinkProcessor;

    private Entry(ConfigInfo info) {
      this.info = info;
    }

    public CommentLinkProcessor getCommentLinkProcessor() {
      if (commentLinkProcessor == null) {
        commentLinkProcessor = new CommentLinkProcessor(info.commentlinks());
      }
      return commentLinkProcessor;
    }

    public ThemeInfo getTheme() {
      return info.theme();
    }
  }

  public static void get(Project.NameKey name, AsyncCallback<Entry> cb) {
    instance.getImpl(name.get(), cb);
  }

  public static void get(Change.Id changeId, AsyncCallback<Entry> cb) {
    instance.getImpl(changeId.get(), cb);
  }

  public static void add(ChangeInfo info) {
    instance.changeToProject.put(info.legacy_id().get(), info.project());
  }

  private final LinkedHashMap<String, Entry> cache;
  private final LinkedHashMap<Integer, String> changeToProject;

  protected ConfigInfoCache() {
    cache = new LinkedHashMap<String, Entry>(PROJECT_LIMIT) {
      private static final long serialVersionUID = 1L;

      @Override
      protected boolean removeEldestEntry(
          Map.Entry<String, ConfigInfoCache.Entry> e) {
        return size() > PROJECT_LIMIT;
      }
    };

    changeToProject = new LinkedHashMap<Integer, String>(CHANGE_LIMIT) {
      private static final long serialVersionUID = 1L;

      @Override
      protected boolean removeEldestEntry(Map.Entry<Integer, String> e) {
        return size() > CHANGE_LIMIT;
      }
    };
  }

  private void getImpl(final String name, final AsyncCallback<Entry> cb) {
    Entry e = cache.get(name);
    if (e != null) {
      cb.onSuccess(e);
      return;
    }
    ProjectApi.getConfig(new Project.NameKey(name),
        new AsyncCallback<ConfigInfo>() {
          @Override
          public void onSuccess(ConfigInfo result) {
            Entry e = new Entry(result);
            cache.put(name, e);
            cb.onSuccess(e);
          }

          @Override
          public void onFailure(Throwable caught) {
            cb.onFailure(caught);
          }
        });
  }

  private void getImpl(final Integer id, final AsyncCallback<Entry> cb) {
    String name = changeToProject.get(id);
    if (name != null) {
      getImpl(name, cb);
      return;
    }
    ChangeApi.change(id).get(new AsyncCallback<ChangeInfo>() {
      @Override
      public void onSuccess(ChangeInfo result) {
        changeToProject.put(id, result.project());
        getImpl(result.project(), cb);
      }

      @Override
      public void onFailure(Throwable caught) {
        cb.onFailure(caught);
      }
    });
  }
}
