// Copyright (C) 2009 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.server.account;

import com.google.gerrit.common.data.GroupDescription;
import com.google.gerrit.common.data.GroupDetail;
import com.google.gerrit.common.data.GroupReference;
import com.google.gerrit.common.errors.NoSuchGroupException;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.AccountGroupIncludeByUuid;
import com.google.gerrit.reviewdb.client.AccountGroupMember;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.Callable;

public class GroupDetailFactory implements Callable<GroupDetail> {
  public interface Factory {
    GroupDetailFactory create(AccountGroup.Id groupId);
  }

  private final ReviewDb db;
  private final GroupControl.Factory groupControl;
  private final GroupCache groupCache;
  private final GroupBackend groupBackend;
  private final AccountInfoCacheFactory aic;
  private final GroupInfoCacheFactory gic;

  private final AccountGroup.Id groupId;
  private GroupControl control;

  @Inject
  GroupDetailFactory(final ReviewDb db,
      final GroupControl.Factory groupControl, final GroupCache groupCache,
      final GroupBackend groupBackend,
      final AccountInfoCacheFactory.Factory accountInfoCacheFactory,
      final GroupInfoCacheFactory.Factory groupInfoCacheFactory,
      @Assisted final AccountGroup.Id groupId) {
    this.db = db;
    this.groupControl = groupControl;
    this.groupCache = groupCache;
    this.groupBackend = groupBackend;
    this.aic = accountInfoCacheFactory.create();
    this.gic = groupInfoCacheFactory.create();

    this.groupId = groupId;
  }

  @Override
  public GroupDetail call() throws OrmException, NoSuchGroupException {
    control = groupControl.validateFor(groupId);
    final AccountGroup group = groupCache.get(groupId);
    final GroupDetail detail = new GroupDetail();
    detail.setGroup(group);
    GroupDescription.Basic ownerGroup = groupBackend.get(group.getOwnerGroupUUID());
    if (ownerGroup != null) {
      detail.setOwnerGroup(GroupReference.forGroup(ownerGroup));
    }
    switch (group.getType()) {
      case INTERNAL:
        detail.setMembers(loadMembers());
        detail.setIncludes(loadIncludes());
        break;
      case SYSTEM:
        break;
    }
    detail.setAccounts(aic.create());
    detail.setCanModify(control.isOwner());
    return detail;
  }

  private List<AccountGroupMember> loadMembers() throws OrmException {
    List<AccountGroupMember> members = new ArrayList<AccountGroupMember>();
    for (final AccountGroupMember m : db.accountGroupMembers().byGroup(groupId)) {
      if (control.canSeeMember(m.getAccountId())) {
        aic.want(m.getAccountId());
        members.add(m);
      }
    }

    Collections.sort(members, new Comparator<AccountGroupMember>() {
      public int compare(final AccountGroupMember o1,
          final AccountGroupMember o2) {
        final Account a = aic.get(o1.getAccountId());
        final Account b = aic.get(o2.getAccountId());
        return n(a).compareTo(n(b));
      }

      private String n(final Account a) {
        String n = a.getFullName();
        if (n != null && n.length() > 0) {
          return n;
        }

        n = a.getPreferredEmail();
        if (n != null && n.length() > 0) {
          return n;
        }

        return a.getId().toString();
      }
    });
    return members;
  }

  private List<AccountGroupIncludeByUuid> loadIncludes() throws OrmException {
    List<AccountGroupIncludeByUuid> groups = new ArrayList<AccountGroupIncludeByUuid>();

    for (final AccountGroupIncludeByUuid m : db.accountGroupIncludesByUuid().byGroup(groupId)) {
      if (control.canSeeGroup(m.getIncludeUUID())) {
        gic.want(m.getIncludeUUID());
        groups.add(m);
      }
    }

    Collections.sort(groups, new Comparator<AccountGroupIncludeByUuid>() {
      public int compare(final AccountGroupIncludeByUuid o1,
          final AccountGroupIncludeByUuid o2) {
        GroupDescription.Basic a = gic.get(o1.getIncludeUUID());
        GroupDescription.Basic b = gic.get(o2.getIncludeUUID());
        return n(a).compareTo(n(b));
      }

      private String n (GroupDescription.Basic a) {
        if (a == null) {
          return "";
        }

        String n = a.getName();
        if (n != null && n.length() > 0) {
          return n;
        }
        return a.getGroupUUID().get();
      }
    });

    return groups;
  }
}
