/*
 * 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.spotify.reaper.core;

import org.apache.cassandra.repair.RepairParallelism;
import org.joda.time.DateTime;

public class RepairSchedule {

  private final long id;

  private final long repairUnitId;
  private final State state;
  private final int daysBetween;
  private final DateTime nextActivation;
  private final int segmentCount;
  private final RepairParallelism repairParallelism;
  private final String owner;
  private final DateTime creationTime;
  private final DateTime pauseTime;
  private final String lastEvent;

  private RepairSchedule(Builder builder, long id) {
    this.id = id;
    this.repairUnitId = builder.repairUnitId;
    this.state = builder.state;
    this.daysBetween = builder.daysBetween;
    this.nextActivation = builder.nextActivation;
    this.segmentCount = builder.segmentCount;
    this.repairParallelism = builder.repairParallelism;
    this.owner = builder.owner;
    this.creationTime = builder.creationTime;
    this.pauseTime = builder.pauseTime;
    this.lastEvent = builder.lastEvent;
  }

  public long getId() {
    return id;
  }

  public long getRepairUnitId() {
    return repairUnitId;
  }

  public State getState() {
    return state;
  }

  public int getDaysBetween() {
    return daysBetween;
  }

  public DateTime getFollowingActivation() {
    return getNextActivation().plusDays(getDaysBetween());
  }

  public DateTime getNextActivation() {
    return nextActivation;
  }

  public int getSegmentCount() {
    return segmentCount;
  }

  public RepairParallelism getRepairParallelism() {
    return repairParallelism;
  }

  public String getOwner() {
    return owner;
  }

  public DateTime getCreationTime() {
    return creationTime;
  }

  public DateTime getPauseTime() {
    return pauseTime;
  }

  public String getLastEvent() {
    return lastEvent;
  }

  public Builder with() {
    return new Builder(this);
  }

  public enum State {
    RUNNING,
    PAUSED
  }

  public static class Builder {

    public final long repairUnitId;
    private State state;
    private int daysBetween;
    private DateTime nextActivation;
    private int segmentCount;
    private RepairParallelism repairParallelism;
    private String owner;
    private DateTime creationTime;
    private DateTime pauseTime;
    private String lastEvent = "no events";

    public Builder(long repairUnitId, State initialState, DateTime creationTime,
                   int segmentCount, RepairParallelism repairParallelism) {
      this.repairUnitId = repairUnitId;
      this.state = initialState;
      this.creationTime = creationTime;
      this.segmentCount = segmentCount;
      this.repairParallelism = repairParallelism;
    }

    private Builder(RepairSchedule original) {
      repairUnitId = original.repairUnitId;
      state = original.state;
      creationTime = original.creationTime;
      owner = original.owner;
      pauseTime = original.pauseTime;
      lastEvent = original.lastEvent;
      segmentCount = original.segmentCount;
      repairParallelism = original.repairParallelism;
    }

    public Builder runState(State state) {
      this.state = state;
      return this;
    }

    public Builder daysBetween(int daysBetween) {
      this.daysBetween = daysBetween;
      return this;
    }

    public Builder nextActivation(DateTime nextActivation) {
      this.nextActivation = nextActivation;
      return this;
    }

    public Builder segmentCount(int segmentCount) {
      this.segmentCount = segmentCount;
      return this;
    }

    public Builder repairParallelism(RepairParallelism repairParallelism) {
      this.repairParallelism = repairParallelism;
      return this;
    }

    public Builder owner(String owner) {
      this.owner = owner;
      return this;
    }

    public Builder creationTime(DateTime creationTime) {
      this.creationTime = creationTime;
      return this;
    }

    public Builder pauseTime(DateTime pauseTime) {
      this.pauseTime = pauseTime;
      return this;
    }

    public Builder lastEvent(String lastEvent) {
      this.lastEvent = lastEvent;
      return this;
    }

    public RepairSchedule build(long id) {
      return new RepairSchedule(this, id);
    }
  }
}

@@ -589,16 +589,57 @@
 .core;%0A%0A
+import com.google.common.collect.Lists;%0A%0A
 import o
@@ -716,16 +716,40 @@
 eTime;%0A%0A
+import java.util.List;%0A%0A
 public c
@@ -935,16 +935,55 @@
 vation;%0A
+  private final List%3CLong%3E runHistory;%0A
   privat
@@ -1440,24 +1440,66 @@
 Activation;%0A
+    this.runHistory = builder.runHistory;%0A
     this.seg
@@ -2144,32 +2144,98 @@
 ctivation;%0A  %7D%0A%0A
+  public List%3CLong%3E getRunHistory() %7B%0A    return runHistory;%0A  %7D%0A%0A
   public int get
@@ -2878,24 +2878,59 @@
 Activation;%0A
+    private List%3CLong%3E runHistory;%0A
     private 
@@ -3379,35 +3379,41 @@
 his.
-creationTime = creationTime
+runHistory = Lists.newArrayList()
 ;%0A  
@@ -3492,32 +3492,72 @@
 airParallelism;%0A
+      this.creationTime = creationTime;%0A
     %7D%0A%0A    priva
@@ -3678,248 +3678,378 @@
     
-creationTime = original.creationTime;%0A      owner = original.owner;%0A      pauseTime = original.pauseTime;%0A      lastEvent = original.lastEvent;%0A      segmentCount = original.segmentCount;%0A      repairParallelism = original.repairParallelism
+daysBetween = original.daysBetween;%0A      nextActivation = original.nextActivation;%0A      runHistory = original.runHistory;%0A      segmentCount = original.segmentCount;%0A      repairParallelism = original.repairParallelism;%0A      owner = original.owner;%0A      creationTime = original.creationTime;%0A      pauseTime = original.pauseTime;%0A      lastEvent = original.lastEvent
 ;%0A  
@@ -4385,32 +4385,133 @@
 rn this;%0A    %7D%0A%0A
+    public Builder addRun(Long newRunId) %7B%0A      runHistory.add(newRunId);%0A      return this;%0A    %7D%0A%0A
     public Build

Add runHistory to RepairSchedule and fix missing fields in Builder's "copy constructor"