package com.hubspot.singularity.data;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.utils.ZKPaths;

import com.codahale.metrics.MetricRegistry;
import com.google.common.base.Charsets;
import com.google.common.base.Optional;
import com.google.common.io.BaseEncoding;
import com.google.inject.Inject;
import com.hubspot.singularity.SingularityUserSettings;
import com.hubspot.singularity.config.SingularityConfiguration;
import com.hubspot.singularity.data.transcoders.Transcoder;

public class UserManager extends CuratorManager {

  private final Transcoder<SingularityUserSettings> settingsTranscoder;
  private final SingularityValidator validator;

  private static final String USER_ROOT = "/users";

  private static final String SETTINGS_ROOT = USER_ROOT + "/settings";

  @Inject
  public UserManager(CuratorFramework curator, SingularityConfiguration configuration, MetricRegistry metricRegistry,
                     Transcoder<SingularityUserSettings> settingsTranscoder, SingularityValidator validator) {
    super(curator, configuration, metricRegistry);
    this.settingsTranscoder = settingsTranscoder;
    this.validator = validator;
  }

  private String encodeUserId(String userId) {
    validator.checkUserId(userId);
    return BaseEncoding.base64Url().encode(userId.getBytes(Charsets.UTF_8));
  }

  private String getUserSettingsPath(String userId) {
    return ZKPaths.makePath(SETTINGS_ROOT, encodeUserId(userId));
  }

  public void updateUserSettings(String userId, SingularityUserSettings userSettings) {
    save(getUserSettingsPath(userId), userSettings, settingsTranscoder);
  }

  public Optional<SingularityUserSettings> getUserSettings(String userId) {
    return getData(getUserSettingsPath(userId), settingsTranscoder);
  }

  public void deleteUserSettings(String userId) {
    delete(getUserSettingsPath(userId));
  }

}

@@ -32,16 +32,69 @@
 .data;%0A%0A
+import java.util.Collections;%0Aimport java.util.Set;%0A%0A
 import o
@@ -1682,32 +1682,1230 @@
 anscoder);%0A  %7D%0A%0A
+  private Optional%3CSingularityUserSettings%3E guaranteeSettingsElseDefault(String path, SingularityUserSettings defaultSettings) %7B%0A    final Optional%3CSingularityUserSettings%3E settings = getData(path, settingsTranscoder);%0A    if (!settings.isPresent()) %7B%0A      save(path, defaultSettings, settingsTranscoder);%0A    %7D%0A    return settings;%0A  %7D%0A%0A  public void addStarredRequestIds(String userId, Set%3CString%3E starredRequestIds) %7B%0A    final String path = getUserSettingsPath(userId);%0A    final Optional%3CSingularityUserSettings%3E settings = guaranteeSettingsElseDefault(path, new SingularityUserSettings(userId, starredRequestIds));%0A    if (settings.isPresent()) %7B%0A      save(path, settings.get().addStarredRequestIds(starredRequestIds), settingsTranscoder);%0A    %7D%0A  %7D%0A%0A  public void deleteStarredRequestIds(String userId, Set%3CString%3E starredRequestIds) %7B%0A    final String path = getUserSettingsPath(userId);%0A    final Optional%3CSingularityUserSettings%3E settings = guaranteeSettingsElseDefault(path, new SingularityUserSettings(userId, Collections.%3CString%3EemptySet()));%0A    if (settings.isPresent()) %7B%0A      save(path, settings.get().deleteStarredRequestIds(starredRequestIds), settingsTranscoder);%0A    %7D%0A  %7D%0A%0A
   public Optiona

Add efficient add/delete starred requests methods to UserManager