// Path: src/main/java/org/arbeitspferde/groningen/config/GroningenConfig.java
// public interface SubjectGroupConfig {
// 
//   /**
//    * Returns the {@link ClusterConfig} of which this {@link SubjectGroupConfig} is a child.
//    *
//    * @return {@link ClusterConfig} of which this {@link SubjectGroupConfig} is a child.
//    * Can be null if used outside the GroningenConfig config hierarchy
//    */
//   @Nullable
//   public ClusterConfig getParentCluster();
// 
//   /**
//    * Returns the name of the subject group.
//    *
//    * @return the name of the subject group.
//    */
//   public String getName();
// 
//   /**
//    * Returns a {@link String} representing the user that should be used to access the
//    * subject group.
//    *
//    * @return The name of user.
//    * @throws NullPointerException no user was supplied in the configuration hierarchy
//    */
//   public String getUser();
// 
//   /**
//    * Returns a {@link String} representing the path where per-subject experiment settings files
//    * will be stored. These files will be read by jvm_arg_injector and it will inject their
//    * contents into the experiments' subjects' command line. For every subject group's member,
//    * Groningen will create a file with a full path looking like this:
//    * <exp_settings_files_dir>/<subject_index>
//    *
//    * @return Full path to the experiments settings files directory for the subjects of this
//    *         subject group
//    * @throws NullPointerException no experiment settings files directory path was specified for
//    *         this subject group
//    */
//   public String getExperimentSettingsFilesDir();
// 
//   /**
//    * Returns a {@link List} of {@link SubjectConfig} representing either
//    * configuration for all of the subjects or none. Groningen will use all subjects in a subject
//    * group, requiring separation of the test instances from the nontest instances into separate
//    * subject groups. If the list specifies a partial set of the subjects, the remaining subjects
//    * will have values chosen at random. This allows for injecting known argument sets to see how
//    * they fair with randomly chosen values.
//    *
//    * @return list of configurations which can be linked to specific or random subjects depending
//    * on the internals of the SubjectConfig
//    */
//   public ImmutableList<SubjectConfig> getSpecialSubjectConfigs();
// 
//   /**
//    * Returns an int that represents the number of subjects in a subject group that Groningen is
//    * permitted to control for experimentation purposes. Setting this to value N implies that
//    * subjects 0 to N-1 within a subject group are controlled by Groningen.
//    */
//   public int getNumberOfSubjects();
// 
//   /**
//    * Returns the max number of seconds that an experimental subject is allowed to _not_ return OK
//    * on health checks probes when running an experiment. Defaulting to 0 implies that Groningen
//    * will pick a reasonable value for this (currently 300 secs).
//    */
//   public int getSubjectWarmupTimeout();
// 
//   /**
//    * Returns True if this subject group has a custom restart command.  Otherwise, an
//    * automatically-generated one should be used.
//    */
//   public boolean hasRestartCommand();
// 
//   /**
//    * Returns the custom restart command if one is specified.
//    */
//   public String[] getRestartCommand();
// 
//   /**
//    * Returns the number of subjects with default settings. These subjects won't be touched by
//    * hypothesizer. This number should be less than total number of subjects in experiment.
//    */
//   public int getNumberOfDefaultSubjects();
// }
// 
// Path: src/main/java/org/arbeitspferde/groningen/utility/TemporaryFailure.java
// public class TemporaryFailure extends Exception {
//   public TemporaryFailure(final String message) {
//     super(message);
//   }
// 
//   public TemporaryFailure(final String message, final Throwable e) {
//     super(message, e);
//   }
// 
//   public TemporaryFailure(final Throwable e) {
//     super(e);
//   }
// }


import com.google.common.base.Joiner;
import com.google.common.base.Objects;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import org.arbeitspferde.groningen.config.GroningenConfig.SubjectGroupConfig;
import org.arbeitspferde.groningen.config.NamedConfigParam;
import org.arbeitspferde.groningen.proto.Params.GroningenParams;
import org.arbeitspferde.groningen.utility.PermanentFailure;
import org.arbeitspferde.groningen.utility.TemporaryFailure;
import java.util.List;
/* Copyright 2012 Google, Inc.
 *
 * 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 org.arbeitspferde.groningen.subject;




/**
 * This class represents an experimental population of {@link Subject}s.
 */
public class SubjectGroup {
  private static final Joiner slashJoiner = Joiner.on("/");
  private static final Joiner commaJoiner = Joiner.on(",");

  @Inject
  @NamedConfigParam("subject_manipulation_deadline_ms")
  private final int populationCensusCollectionDeadline =
      GroningenParams.getDefaultInstance().getSubjectManipulationDeadlineMs();

  private final String clusterName;
  private final String name;
  private final String userName;
  private final SubjectGroupConfig config;
  private final List<Subject> subjects;
  private final ServingAddressGenerator servingAddressbuilder;

  public SubjectGroup(final String clusterName, final String name,
      final String userName, final SubjectGroupConfig groupConfig,
      final ServingAddressGenerator servingAddressBuilder) {
    this.clusterName = clusterName;
    this.name = name;
    this.userName = userName;
    this.config = groupConfig;
    this.subjects = Lists.newArrayList();
    this.servingAddressbuilder = servingAddressBuilder;
  }

  /** Initializes subject data
   *
   * You must call initialize before accessing any of the subject data or you won't find any :)
   *
   * @param manipulator The means for manipulating subject state.
   * @param origSubjectList The original subject list that the new list is concatenated with.
   *                        This has the side effect of concatinating the new list onto the
   *                        origSubjectList.
   *
   * @return The list of subjects within this subject we control concatenated onto the origSubjectList
   */
  public List<Subject> initialize(SubjectManipulator manipulator, List<Subject> origSubjectList)
// Path: src/main/java/org/arbeitspferde/groningen/config/GroningenConfig.java
// public interface SubjectGroupConfig {
// 
//   /**
//    * Returns the {@link ClusterConfig} of which this {@link SubjectGroupConfig} is a child.
//    *
//    * @return {@link ClusterConfig} of which this {@link SubjectGroupConfig} is a child.
//    * Can be null if used outside the GroningenConfig config hierarchy
//    */
//   @Nullable
//   public ClusterConfig getParentCluster();
// 
//   /**
//    * Returns the name of the subject group.
//    *
//    * @return the name of the subject group.
//    */
//   public String getName();
// 
//   /**
//    * Returns a {@link String} representing the user that should be used to access the
//    * subject group.
//    *
//    * @return The name of user.
//    * @throws NullPointerException no user was supplied in the configuration hierarchy
//    */
//   public String getUser();
// 
//   /**
//    * Returns a {@link String} representing the path where per-subject experiment settings files
//    * will be stored. These files will be read by jvm_arg_injector and it will inject their
//    * contents into the experiments' subjects' command line. For every subject group's member,
//    * Groningen will create a file with a full path looking like this:
//    * <exp_settings_files_dir>/<subject_index>
//    *
//    * @return Full path to the experiments settings files directory for the subjects of this
//    *         subject group
//    * @throws NullPointerException no experiment settings files directory path was specified for
//    *         this subject group
//    */
//   public String getExperimentSettingsFilesDir();
// 
//   /**
//    * Returns a {@link List} of {@link SubjectConfig} representing either
//    * configuration for all of the subjects or none. Groningen will use all subjects in a subject
//    * group, requiring separation of the test instances from the nontest instances into separate
//    * subject groups. If the list specifies a partial set of the subjects, the remaining subjects
//    * will have values chosen at random. This allows for injecting known argument sets to see how
//    * they fair with randomly chosen values.
//    *
//    * @return list of configurations which can be linked to specific or random subjects depending
//    * on the internals of the SubjectConfig
//    */
//   public ImmutableList<SubjectConfig> getSpecialSubjectConfigs();
// 
//   /**
//    * Returns an int that represents the number of subjects in a subject group that Groningen is
//    * permitted to control for experimentation purposes. Setting this to value N implies that
//    * subjects 0 to N-1 within a subject group are controlled by Groningen.
//    */
//   public int getNumberOfSubjects();
// 
//   /**
//    * Returns the max number of seconds that an experimental subject is allowed to _not_ return OK
//    * on health checks probes when running an experiment. Defaulting to 0 implies that Groningen
//    * will pick a reasonable value for this (currently 300 secs).
//    */
//   public int getSubjectWarmupTimeout();
// 
//   /**
//    * Returns True if this subject group has a custom restart command.  Otherwise, an
//    * automatically-generated one should be used.
//    */
//   public boolean hasRestartCommand();
// 
//   /**
//    * Returns the custom restart command if one is specified.
//    */
//   public String[] getRestartCommand();
// 
//   /**
//    * Returns the number of subjects with default settings. These subjects won't be touched by
//    * hypothesizer. This number should be less than total number of subjects in experiment.
//    */
//   public int getNumberOfDefaultSubjects();
// }
// 
// Path: src/main/java/org/arbeitspferde/groningen/utility/TemporaryFailure.java
// public class TemporaryFailure extends Exception {
//   public TemporaryFailure(final String message) {
//     super(message);
//   }
// 
//   public TemporaryFailure(final String message, final Throwable e) {
//     super(message, e);
//   }
// 
//   public TemporaryFailure(final Throwable e) {
//     super(e);
//   }
// }


// Path: src/main/java/org/arbeitspferde/groningen/subject/SubjectGroup.java
import com.google.common.base.Joiner;
import com.google.common.base.Objects;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import org.arbeitspferde.groningen.config.GroningenConfig.SubjectGroupConfig;
import org.arbeitspferde.groningen.config.NamedConfigParam;
import org.arbeitspferde.groningen.proto.Params.GroningenParams;
import org.arbeitspferde.groningen.utility.PermanentFailure;
import org.arbeitspferde.groningen.utility.TemporaryFailure;
import java.util.List;

/* Copyright 2012 Google, Inc.
 *
 * 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 org.arbeitspferde.groningen.subject;




/**
 * This class represents an experimental population of {@link Subject}s.
 */
public class SubjectGroup {
  private static final Joiner slashJoiner = Joiner.on("/");
  private static final Joiner commaJoiner = Joiner.on(",");

  @Inject
  @NamedConfigParam("subject_manipulation_deadline_ms")
  private final int populationCensusCollectionDeadline =
      GroningenParams.getDefaultInstance().getSubjectManipulationDeadlineMs();

  private final String clusterName;
  private final String name;
  private final String userName;
  private final SubjectGroupConfig config;
  private final List<Subject> subjects;
  private final ServingAddressGenerator servingAddressbuilder;

  public SubjectGroup(final String clusterName, final String name,
      final String userName, final SubjectGroupConfig groupConfig,
      final ServingAddressGenerator servingAddressBuilder) {
    this.clusterName = clusterName;
    this.name = name;
    this.userName = userName;
    this.config = groupConfig;
    this.subjects = Lists.newArrayList();
    this.servingAddressbuilder = servingAddressBuilder;
  }

  /** Initializes subject data
   *
   * You must call initialize before accessing any of the subject data or you won't find any :)
   *
   * @param manipulator The means for manipulating subject state.
   * @param origSubjectList The original subject list that the new list is concatenated with.
   *                        This has the side effect of concatinating the new list onto the
   *                        origSubjectList.
   *
   * @return The list of subjects within this subject we control concatenated onto the origSubjectList
   */
  public List<Subject> initialize(SubjectManipulator manipulator, List<Subject> origSubjectList)
      throws PermanentFailure, TemporaryFailure {