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

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

import java.util.List;

import com.google.common.collect.ImmutableList;

import uk.co.bristlecone.voltdb.wrapgen.source.ProcReturnType;
import uk.co.bristlecone.voltdb.wrapgen.source.RunParameter;
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 final String name;
  private final List<RunParameter> parameters;
  private final ProcReturnType returnType;
  private final String packageName;

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

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

  /**
   * @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;
  }

  /**
   * @return the stored procedure's package
   */
  public String packageName() {
    return packageName;
  }

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

    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 = ImmutableList.copyOf(parameters);
      return this;
    }

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

    public Builder setPackageName(String packageName) {
      checkArgument(packageName != null, "packageName must not be null");
      this.packageName = packageName;
      return this;
    }

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

@@ -2055,126 +2055,17 @@
 heck
-Argument(name != null, %22name must not be null%22);%0A      checkArgument(!name.equals(%22%22), %22name must not be empty String%22
+Name(name
 );%0A 
@@ -2194,66 +2194,29 @@
 heck
-Argument(parameters != null, %22parameters must not be null%22
+Parameters(parameters
 );%0A 
@@ -2375,60 +2375,29 @@
 heck
-Argument(name != null, %22returnType must not be null%22
+ReturnType(returnType
 );%0A 
@@ -2528,83 +2528,588 @@
 heck
-Argument(packageName != null, %22packageName must not be null%22);%0A      this.p
+PackageName(packageName);%0A      this.packageName = packageName;%0A      return this;%0A    %7D%0A%0A    private void checkName(String name) %7B%0A      checkArgument(name != null, %22name must not be null%22);%0A      checkArgument(!name.equals(%22%22), %22name must not be empty String%22);%0A    %7D%0A%0A    private void checkParameters(List%3CRunParameter%3E parameters) %7B%0A      checkArgument(parameters != null, %22parameters must not be null%22);%0A    %7D%0A%0A    private void checkReturnType(ProcReturnType returnType) %7B%0A      checkArgument(returnType != null, %22returnType must not be null%22);%0A    %7D%0A%0A    private void checkP
 acka
@@ -3106,34 +3106,39 @@
 checkPackageName
- =
+(String
  packageName;%0A  
@@ -3137,65 +3137,252 @@
 Name
-;
+) %7B
 %0A      
-return this;%0A    %7D%0A%0A    public ProcData build() %7B
+checkArgument(packageName != null, %22packageName must not be null%22);%0A    %7D%0A%0A    public ProcData build() %7B%0A      checkName(name);%0A      checkParameters(parameters);%0A      checkReturnType(returnType);%0A      checkPackageName(packageName);
 %0A   

clean up ProcData checks for valid builder field values