package uk.co.bristlecone.voltdb.wrapgen.builder;

import static com.google.common.base.Preconditions.checkArgument;

import java.util.List;

import uk.co.bristlecone.voltdb.wrapgen.source.RunParameter;
import uk.co.bristlecone.voltdb.wrapgen.source.ProcReturnType;
import uk.co.bristlecone.voltdb.wrapgen.source.SourceFile;

/**
 * An immutable class representing the metadata needed to build a wrapgen runner
 * 
 * @author christo
 */
public class ProcData {
  private String name;
  private List<RunParameter> parameters;
  private ProcReturnType returnType;

  private ProcData(String name, List<RunParameter> parameters, ProcReturnType returnType) {
    this.name = name;
    this.parameters = parameters;
    this.returnType = returnType;
  }

  private ProcData(SourceFile source) {
    this.name = source.voltProcedureName();
    this.parameters = source.runMethodParameters();
    this.returnType = source.runMethodReturnType();
  }

  /**
   * @return the (unqualified) name of the stored procedure class
   */
  public String name() {
    return name;
  }

  /**
   * @return the parameters to the stored procedure's <code>run</code> method
   */
  public List<RunParameter> parameters() {
    return parameters;
  }

  /**
   * @return the stored procedure's return type
   */
  public ProcReturnType returnType() {
    return returnType;
  }

  /**
   * Allows clear, type-safe building of a ProcData
   * 
   * @author christo
   */
  public static class Builder {
    private String name;
    private List<RunParameter> parameters;
    private ProcReturnType returnType;

    public Builder() {
      // intentionally left blank
    }

    public Builder setName(String name) {
      checkArgument(name != null, "name must not be null");
      checkArgument(!name.equals(""), "name must not be empty String");
      this.name = name;
      return this;
    }

    public Builder setParameters(List<RunParameter> parameters) {
      checkArgument(parameters != null, "parameters must not be null");
      this.parameters = parameters;
      return this;
    }

    public Builder setReturnType(ProcReturnType returnType) {
      checkArgument(name != null, "returnType must not be null");
      this.returnType = returnType;
      return this;
    }

    public ProcData build() {
      return new ProcData(name, parameters, returnType);
    }
  }
}

@@ -182,28 +182,30 @@
 .source.
-RunParameter
+ProcReturnType
 ;%0Aimport
@@ -241,38 +241,36 @@
 pgen.source.
-ProcReturnType
+RunParameter
 ;%0Aimport uk.
@@ -551,24 +551,54 @@
  returnType;
+%0A  private String packageName;
 %0A%0A  private 
@@ -667,32 +667,52 @@
 nType returnType
+, String packageName
 ) %7B%0A    this.nam
@@ -785,24 +785,60 @@
 returnType;%0A
+    this.packageName = packageName;%0A
   %7D%0A%0A  priva
@@ -1018,16 +1018,61 @@
 Type();%0A
+    this.packageName = source.packageName();%0A
   %7D%0A%0A  /
@@ -1473,32 +1473,149 @@
 eturnType;%0A  %7D%0A%0A
+  /**%0A   * @return the stored procedure's package%0A   */%0A  public String packageName() %7B%0A    return packageName;%0A  %7D%0A%0A
   /**%0A   * Allow
@@ -1827,16 +1827,48 @@
 urnType;
+%0A    private String packageName;
 %0A%0A    pu
@@ -2531,32 +2531,226 @@
 rn this;%0A    %7D%0A%0A
+    public Builder setPackageName(String packageName) %7B%0A      checkArgument(packageName != null, %22packageName must not be null%22);%0A      this.packageName = packageName;%0A      return this;%0A    %7D%0A%0A
     public ProcD
@@ -2817,16 +2817,29 @@
 turnType
+, packageName
 );%0A    %7D

add packageName to ProcData and ProcData.Builder