// Copyright (C) 2014 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.googlesource.gerrit.plugins.serviceuser;

import static com.googlesource.gerrit.plugins.serviceuser.CreateServiceUser.KEY_CREATOR_ID;
import static com.googlesource.gerrit.plugins.serviceuser.CreateServiceUser.USER;

import com.google.common.collect.Maps;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.config.ConfigResource;
import com.google.gerrit.server.git.ProjectLevelConfig;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;

import com.googlesource.gerrit.plugins.serviceuser.GetServiceUser.ServiceUserInfo;

import org.eclipse.jgit.lib.Config;

import java.util.Map;

public class ListServiceUsers implements RestReadView<ConfigResource> {
  private final Provider<CurrentUser> userProvider;
  private final IdentifiedUser.GenericFactory userFactory;
  private final ProjectLevelConfig storage;
  private final AccountCache accountCache;
  private final Provider<GetServiceUser> getServiceUser;

  @Inject
  ListServiceUsers(Provider<CurrentUser> userProvider,
      IdentifiedUser.GenericFactory userFactory, @PluginName String pluginName,
      ProjectCache projectCache, AccountCache accountCache,
      Provider<GetServiceUser> getServiceUser) {
    this.userProvider = userProvider;
    this.userFactory = userFactory;
    this.storage = projectCache.getAllProjects().getConfig(pluginName + ".db");
    this.accountCache = accountCache;
    this.getServiceUser = getServiceUser;
  }

  @Override
  public Map<String, ServiceUserInfo> apply(ConfigResource rscr)
      throws OrmException, AuthException {
    CurrentUser user = userProvider.get();
    if (user == null || !user.isIdentifiedUser()) {
      throw new AuthException("Authentication required");
    }

    Map<String, ServiceUserInfo> accounts = Maps.newTreeMap();
    Config db = storage.get();
    boolean isAdmin = user.getCapabilities().canAdministrateServer();
    for (String username : db.getSubsections(USER)) {
      Account.Id createdBy =
          new Account.Id(db.getInt(USER, username, KEY_CREATOR_ID, -1));
      if (isAdmin || ((IdentifiedUser)user).getAccountId().equals(createdBy)) {
        AccountState account = accountCache.getByUsername(username);
        if (account != null) {
          ServiceUserInfo info;
          try {
            info = getServiceUser.get().apply(
                new ServiceUserResource(userFactory.create(account.getAccount().getId())));
            info.username = null;
            accounts.put(username, info);
          } catch (ResourceNotFoundException e) {
            // ignore this service user
          }
        }
      }
    }
    return accounts;
  }
}

@@ -660,100 +660,8 @@
 r;%0A%0A
-import static com.googlesource.gerrit.plugins.serviceuser.CreateServiceUser.KEY_CREATOR_ID;%0A
 impo
@@ -889,32 +889,86 @@
 .AuthException;%0A
+import com.google.gerrit.extensions.restapi.IdString;%0A
 import com.googl
@@ -1109,120 +1109,22 @@
 rit.
-reviewdb.client.Account;%0Aimport com.google.gerrit.server.CurrentUser;%0Aimport com.google.gerrit.server.Identified
+server.Current
 User
@@ -1785,67 +1785,8 @@
 er;%0A
-  private final IdentifiedUser.GenericFactory userFactory;%0A
   pr
@@ -1868,16 +1868,78 @@
 tCache;%0A
+  private final Provider%3CServiceUserCollection%3E serviceUsers;%0A
   privat
@@ -2062,51 +2062,8 @@
     
- IdentifiedUser.GenericFactory userFactory,
  @Pl
@@ -2089,22 +2089,16 @@
 ginName,
-%0A     
  Project
@@ -2116,16 +2116,22 @@
 ctCache,
+%0A     
  Account
@@ -2145,24 +2145,70 @@
 ccountCache,
+ Provider%3CServiceUserCollection%3E serviceUsers,
 %0A      Provi
@@ -2287,44 +2287,8 @@
 er;%0A
-    this.userFactory = userFactory;%0A
     
@@ -2401,16 +2401,54 @@
 tCache;%0A
+    this.serviceUsers = serviceUsers;%0A
     this
@@ -2868,312 +2868,58 @@
     
-boolean isAdmin = user.getCapabilities().canAdministrateServer();%0A    for (String username : db.getSubsections(USER)) %7B%0A      Account.Id createdBy =%0A          new Account.Id(db.getInt(USER, username, KEY_CREATOR_ID, -1));%0A      if (isAdmin %7C%7C ((IdentifiedUser)user).getAccountId().equals(createdBy)) %7B%0A  
+for (String username : db.getSubsections(USER)) %7B%0A
     
@@ -2987,18 +2987,16 @@
 ;%0A      
-  
 if (acco
@@ -3006,26 +3006,24 @@
  != null) %7B%0A
-  
         Serv
@@ -3048,18 +3048,16 @@
         
-  
 try %7B%0A  
@@ -3068,21 +3068,65 @@
     
-  info = getS
+ServiceUserResource serviceUserResource =%0A              s
 ervi
@@ -3135,116 +3135,161 @@
 User
+s
 .get().
-apply(%0A                new ServiceUserResource(userFactory.create(account.getAccount().getId()))
+parse(new ConfigResource(),%0A                  IdString.fromDecoded(username));%0A          info = getServiceUser.get().apply(serviceUserResource
 );%0A
-  
     
@@ -3326,18 +3326,16 @@
         
- 
- 
 accounts
@@ -3356,18 +3356,16 @@
  info);%0A
-  
         
@@ -3418,19 +3418,10 @@
     
-  
 //
- ignore
  thi
@@ -3438,20 +3438,50 @@
 user
-%0A          %7D
+ is not visible to the caller -%3E ignore it
 %0A   

Fix listing of service users by member of owner group