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 final String classJavaDoc;

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

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

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

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

  /**
   * 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;
    private String classJavaDoc;

    public Builder() {
      // intentionally left blank
    }

    public Builder setName(String name) {
      checkName(name);
      this.name = name;
      return this;
    }

    public Builder setParameters(List<RunParameter> parameters) {
      checkParameters(parameters);
      this.parameters = ImmutableList.copyOf(parameters);
      return this;
    }

    public Builder setReturnType(ProcReturnType returnType) {
      checkReturnType(returnType);
      this.returnType = returnType;
      return this;
    }

    public Builder setPackageName(String packageName) {
      checkPackageName(packageName);
      this.packageName = packageName;
      return this;
    }

    public Builder setClassJavaDoc(String classJavaDoc) {
      checkClassJavaDoc(classJavaDoc);
      this.classJavaDoc = classJavaDoc;
      return this;
    }

    private void checkName(String name) {
      checkArgument(name != null, "name must not be null");
      checkArgument(!name.equals(""), "name must not be empty String");
    }

    private void checkParameters(List<RunParameter> parameters) {
      checkArgument(parameters != null, "parameters must not be null");
    }

    private void checkReturnType(ProcReturnType returnType) {
      checkArgument(returnType != null, "returnType must not be null");
    }

    private void checkPackageName(String packageName) {
      checkArgument(packageName != null, "packageName must not be null");
    }

    private void checkClassJavaDoc(String classJavaDoc) {
      checkArgument(classJavaDoc != null, "classJavaDoc must not be null");
    }

    public ProcData build() {
      checkName(name);
      checkParameters(parameters);
      checkReturnType(returnType);
      checkPackageName(packageName);
      checkClassJavaDoc(classJavaDoc);
      return new ProcData(name, parameters, returnType, packageName, classJavaDoc);
    }
  }
}

@@ -455,17 +455,16 @@
 unner%0A *
- 
 %0A * @aut
@@ -715,16 +715,22 @@
 rocData(
+final 
 String n
@@ -733,16 +733,22 @@
 ng name,
+ final
  List%3CRu
@@ -770,16 +770,22 @@
 ameters,
+ final
  ProcRet
@@ -803,16 +803,28 @@
 urnType,
+%0A      final
  String 
@@ -835,22 +835,22 @@
 ageName,
-%0A     
+ final
  String 
@@ -1053,16 +1053,22 @@
 rocData(
+final 
 SourceFi
@@ -1080,29 +1080,24 @@
 urce) %7B%0A    
-this.
 name = sourc
@@ -1119,29 +1119,24 @@
 Name();%0A    
-this.
 parameters =
@@ -1166,29 +1166,24 @@
 ters();%0A    
-this.
 returnType =
@@ -1213,29 +1213,24 @@
 Type();%0A    
-this.
 packageName 
@@ -1253,29 +1253,24 @@
 Name();%0A    
-this.
 classJavaDoc
@@ -1417,32 +1417,250 @@
 turn name;%0A  %7D%0A%0A
+  /**%0A   * @return the fully qualified name of the stored procedure class%0A   */%0A  public String fullyQualifiedName() %7B%0A    return packageName().equals(%22%22) ? name() : String.format(%22%25s.%25s%22, packageName(), name());%0A  %7D%0A%0A
   /**%0A   * @retu
@@ -2240,17 +2240,16 @@
 ata%0A   *
- 
 %0A   * @a
@@ -2560,24 +2560,30 @@
 der setName(
+final 
 String name)
@@ -2683,32 +2683,38 @@
 r setParameters(
+final 
 List%3CRunParamete
@@ -2874,32 +2874,38 @@
 r setReturnType(
+final 
 ProcReturnType r
@@ -3040,32 +3040,38 @@
  setPackageName(
+final 
 String packageNa
@@ -3204,32 +3204,38 @@
 setClassJavaDoc(
+final 
 String classJava
@@ -3369,24 +3369,30 @@
 d checkName(
+final 
 String name)
@@ -3566,16 +3566,22 @@
 ameters(
+final 
 List%3CRun
@@ -3717,16 +3717,22 @@
 urnType(
+final 
 ProcRetu
@@ -3865,16 +3865,22 @@
 ageName(
+final 
 String p
@@ -4009,16 +4009,22 @@
 JavaDoc(
+final 
 String c

add ProcData#fullyQualifiedName(); misc code tidying b/c of Save Actions