/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.apache.hadoop.record.compiler;

import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.util.*;

import org.apache.commons.io.Charsets;
import org.apache.commons.io.output.FileWriterWithEncoding;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;

/**
 * @deprecated Replaced by <a href="http://hadoop.apache.org/avro/">Avro</a>.
 */
@Deprecated
@InterfaceAudience.Public
@InterfaceStability.Stable
public class JRecord extends JCompType {
  
  class JavaRecord extends JavaCompType {
    
    private String fullName;
    private String name;
    private String module;
    private ArrayList<JField<JavaType>> fields =
      new ArrayList<JField<JavaType>>();
    
    JavaRecord(String name, ArrayList<JField<JType>> flist) {
      super(name, "Record", name, "TypeID.RIOType.STRUCT");
      this.fullName = name;
      int idx = name.lastIndexOf('.');
      this.name = name.substring(idx+1);
      this.module = name.substring(0, idx);
      for (Iterator<JField<JType>> iter = flist.iterator(); iter.hasNext();) {
        JField<JType> f = iter.next();
        fields.add(new JField<JavaType>(f.getName(), f.getType().getJavaType()));
      }
    }
    
    @Override
    String getTypeIDObjectString() {
      return "new org.apache.hadoop.record.meta.StructTypeID(" + 
      fullName + ".getTypeInfo())";
    }

    @Override
    void genSetRTIFilter(CodeBuffer cb, Map<String, Integer> nestedStructMap) {
      // ignore, if we'ev already set the type filter for this record
      if (!nestedStructMap.containsKey(fullName)) {
        // we set the RTI filter here
        cb.append(fullName + ".setTypeFilter(rti.getNestedStructTypeInfo(\""+
            name + "\"));\n");
        nestedStructMap.put(fullName, null);
      }
    }

    // for each typeInfo in the filter, we see if there's a similar one in the record. 
    // Since we store typeInfos in ArrayLists, thsi search is O(n squared). We do it faster
    // if we also store a map (of TypeInfo to index), but since setupRtiFields() is called
    // only once when deserializing, we're sticking with the former, as the code is easier.  
    void genSetupRtiFields(CodeBuffer cb) {
      cb.append("private static void setupRtiFields()\n{\n");
      cb.append("if (null == " + Consts.RTI_FILTER + ") return;\n");
      cb.append("// we may already have done this\n");
      cb.append("if (null != " + Consts.RTI_FILTER_FIELDS + ") return;\n");
      cb.append("int " + Consts.RIO_PREFIX + "i, " + Consts.RIO_PREFIX + "j;\n");
      cb.append(Consts.RTI_FILTER_FIELDS + " = new int [" + 
          Consts.RIO_PREFIX + "rtiFilter.getFieldTypeInfos().size()];\n");
      cb.append("for (" + Consts.RIO_PREFIX + "i=0; " + Consts.RIO_PREFIX + "i<"+
          Consts.RTI_FILTER_FIELDS + ".length; " + Consts.RIO_PREFIX + "i++) {\n");
      cb.append(Consts.RTI_FILTER_FIELDS + "[" + Consts.RIO_PREFIX + "i] = 0;\n");
      cb.append("}\n");
      cb.append("java.util.Iterator<org.apache.hadoop.record.meta." +
          "FieldTypeInfo> " + Consts.RIO_PREFIX + "itFilter = " + 
          Consts.RIO_PREFIX + "rtiFilter.getFieldTypeInfos().iterator();\n");
      cb.append(Consts.RIO_PREFIX + "i=0;\n");
      cb.append("while (" + Consts.RIO_PREFIX + "itFilter.hasNext()) {\n");
      cb.append("org.apache.hadoop.record.meta.FieldTypeInfo " + 
          Consts.RIO_PREFIX + "tInfoFilter = " + 
          Consts.RIO_PREFIX + "itFilter.next();\n");
      cb.append("java.util.Iterator<org.apache.hadoop.record.meta." + 
          "FieldTypeInfo> " + Consts.RIO_PREFIX + "it = " + Consts.RTI_VAR + 
          ".getFieldTypeInfos().iterator();\n");
      cb.append(Consts.RIO_PREFIX + "j=1;\n");
      cb.append("while (" + Consts.RIO_PREFIX + "it.hasNext()) {\n");
      cb.append("org.apache.hadoop.record.meta.FieldTypeInfo " + 
          Consts.RIO_PREFIX + "tInfo = " + Consts.RIO_PREFIX + "it.next();\n");
      cb.append("if (" + Consts.RIO_PREFIX + "tInfo.equals(" +  
          Consts.RIO_PREFIX + "tInfoFilter)) {\n");
      cb.append(Consts.RTI_FILTER_FIELDS + "[" + Consts.RIO_PREFIX + "i] = " +
          Consts.RIO_PREFIX + "j;\n");
      cb.append("break;\n");
      cb.append("}\n");
      cb.append(Consts.RIO_PREFIX + "j++;\n");
      cb.append("}\n");
      /*int ct = 0;
      for (Iterator<JField<JavaType>> i = fields.iterator(); i.hasNext();) {
        ct++;
        JField<JavaType> jf = i.next();
        JavaType type = jf.getType();
        String name = jf.getName();
        if (ct != 1) {
          cb.append("else ");
        }
        type.genRtiFieldCondition(cb, name, ct);
      }
      if (ct != 0) {
        cb.append("else {\n");
        cb.append("rtiFilterFields[i] = 0;\n");
        cb.append("}\n");
      }*/
      cb.append(Consts.RIO_PREFIX + "i++;\n");
      cb.append("}\n");
      cb.append("}\n");
    }

    @Override
    void genReadMethod(CodeBuffer cb, String fname, String tag, boolean decl) {
      if (decl) {
        cb.append(fullName+" "+fname+";\n");
      }
      cb.append(fname+"= new "+fullName+"();\n");
      cb.append(fname+".deserialize(" + Consts.RECORD_INPUT + ",\""+tag+"\");\n");
    }
    
    @Override
    void genWriteMethod(CodeBuffer cb, String fname, String tag) {
      cb.append(fname+".serialize(" + Consts.RECORD_OUTPUT + ",\""+tag+"\");\n");
    }
    
    @Override
    void genSlurpBytes(CodeBuffer cb, String b, String s, String l) {
      cb.append("{\n");
      cb.append("int r = "+fullName+
                ".Comparator.slurpRaw("+b+","+s+","+l+");\n");
      cb.append(s+"+=r; "+l+"-=r;\n");
      cb.append("}\n");
    }
    
    @Override
    void genCompareBytes(CodeBuffer cb) {
      cb.append("{\n");
      cb.append("int r1 = "+fullName+
                ".Comparator.compareRaw(b1,s1,l1,b2,s2,l2);\n");
      cb.append("if (r1 <= 0) { return r1; }\n");
      cb.append("s1+=r1; s2+=r1; l1-=r1; l2-=r1;\n");
      cb.append("}\n");
    }
    
    void genCode(String destDir, ArrayList<String> options) throws IOException {
      String pkg = module;
      String pkgpath = pkg.replaceAll("\\.", "/");
      File pkgdir = new File(destDir, pkgpath);

      final File jfile = new File(pkgdir, name+".java");
      if (!pkgdir.exists()) {
        // create the pkg directory
        boolean ret = pkgdir.mkdirs();
        if (!ret) {
          throw new IOException("Cannnot create directory: "+pkgpath);
        }
      } else if (!pkgdir.isDirectory()) {
        // not a directory
        throw new IOException(pkgpath+" is not a directory.");
      }

      CodeBuffer cb = new CodeBuffer();
      cb.append("// File generated by hadoop record compiler. Do not edit.\n");
      cb.append("package "+module+";\n\n");
      cb.append("public class "+name+
                " extends org.apache.hadoop.record.Record {\n");
      
      // type information declarations
      cb.append("private static final " + 
          "org.apache.hadoop.record.meta.RecordTypeInfo " + 
          Consts.RTI_VAR + ";\n");
      cb.append("private static " + 
          "org.apache.hadoop.record.meta.RecordTypeInfo " + 
          Consts.RTI_FILTER + ";\n");
      cb.append("private static int[] " + Consts.RTI_FILTER_FIELDS + ";\n");
      
      // static init for type information
      cb.append("static {\n");
      cb.append(Consts.RTI_VAR + " = " +
          "new org.apache.hadoop.record.meta.RecordTypeInfo(\"" +
          name + "\");\n");
      for (Iterator<JField<JavaType>> i = fields.iterator(); i.hasNext();) {
        JField<JavaType> jf = i.next();
        String name = jf.getName();
        JavaType type = jf.getType();
        type.genStaticTypeInfo(cb, name);
      }
      cb.append("}\n\n");

      // field definitions
      for (Iterator<JField<JavaType>> i = fields.iterator(); i.hasNext();) {
        JField<JavaType> jf = i.next();
        String name = jf.getName();
        JavaType type = jf.getType();
        type.genDecl(cb, name);
      }

      // default constructor
      cb.append("public "+name+"() { }\n");
      
      // constructor
      cb.append("public "+name+"(\n");
      int fIdx = 0;
      for (Iterator<JField<JavaType>> i = fields.iterator(); i.hasNext(); fIdx++) {
        JField<JavaType> jf = i.next();
        String name = jf.getName();
        JavaType type = jf.getType();
        type.genConstructorParam(cb, name);
        cb.append((!i.hasNext())?"":",\n");
      }
      cb.append(") {\n");
      fIdx = 0;
      for (Iterator<JField<JavaType>> i = fields.iterator(); i.hasNext(); fIdx++) {
        JField<JavaType> jf = i.next();
        String name = jf.getName();
        JavaType type = jf.getType();
        type.genConstructorSet(cb, name);
      }
      cb.append("}\n");

      // getter/setter for type info
      cb.append("public static org.apache.hadoop.record.meta.RecordTypeInfo"
              + " getTypeInfo() {\n");
      cb.append("return " + Consts.RTI_VAR + ";\n");
      cb.append("}\n");
      cb.append("public static void setTypeFilter("
          + "org.apache.hadoop.record.meta.RecordTypeInfo rti) {\n");
      cb.append("if (null == rti) return;\n");
      cb.append(Consts.RTI_FILTER + " = rti;\n");
      cb.append(Consts.RTI_FILTER_FIELDS + " = null;\n");
      // set RTIFilter for nested structs.
      // To prevent setting up the type filter for the same struct more than once, 
      // we use a hash map to keep track of what we've set. 
      Map<String, Integer> nestedStructMap = new HashMap<String, Integer>();
      for (JField<JavaType> jf : fields) {
        JavaType type = jf.getType();
        type.genSetRTIFilter(cb, nestedStructMap);
      }
      cb.append("}\n");

      // setupRtiFields()
      genSetupRtiFields(cb);

      // getters/setters for member variables
      for (Iterator<JField<JavaType>> i = fields.iterator(); i.hasNext();) {
        JField<JavaType> jf = i.next();
        String name = jf.getName();
        JavaType type = jf.getType();
        type.genGetSet(cb, name);
      }
      
      // serialize()
      cb.append("public void serialize("+ 
          "final org.apache.hadoop.record.RecordOutput " + 
          Consts.RECORD_OUTPUT + ", final String " + Consts.TAG + ")\n"+
                "throws java.io.IOException {\n");
      cb.append(Consts.RECORD_OUTPUT + ".startRecord(this," + Consts.TAG + ");\n");
      for (Iterator<JField<JavaType>> i = fields.iterator(); i.hasNext();) {
        JField<JavaType> jf = i.next();
        String name = jf.getName();
        JavaType type = jf.getType();
        type.genWriteMethod(cb, name, name);
      }
      cb.append(Consts.RECORD_OUTPUT + ".endRecord(this," + Consts.TAG+");\n");
      cb.append("}\n");

      // deserializeWithoutFilter()
      cb.append("private void deserializeWithoutFilter("+
                "final org.apache.hadoop.record.RecordInput " + 
                Consts.RECORD_INPUT + ", final String " + Consts.TAG + ")\n"+
                "throws java.io.IOException {\n");
      cb.append(Consts.RECORD_INPUT + ".startRecord(" + Consts.TAG + ");\n");
      for (Iterator<JField<JavaType>> i = fields.iterator(); i.hasNext();) {
        JField<JavaType> jf = i.next();
        String name = jf.getName();
        JavaType type = jf.getType();
        type.genReadMethod(cb, name, name, false);
      }
      cb.append(Consts.RECORD_INPUT + ".endRecord(" + Consts.TAG+");\n");
      cb.append("}\n");
      
      // deserialize()
      cb.append("public void deserialize(final " +
          "org.apache.hadoop.record.RecordInput " + 
          Consts.RECORD_INPUT + ", final String " + Consts.TAG + ")\n"+
          "throws java.io.IOException {\n");
      cb.append("if (null == " + Consts.RTI_FILTER + ") {\n");
      cb.append("deserializeWithoutFilter(" + Consts.RECORD_INPUT + ", " + 
          Consts.TAG + ");\n");
      cb.append("return;\n");
      cb.append("}\n");
      cb.append("// if we're here, we need to read based on version info\n");
      cb.append(Consts.RECORD_INPUT + ".startRecord(" + Consts.TAG + ");\n");
      cb.append("setupRtiFields();\n");
      cb.append("for (int " + Consts.RIO_PREFIX + "i=0; " + Consts.RIO_PREFIX + 
          "i<" + Consts.RTI_FILTER + ".getFieldTypeInfos().size(); " + 
          Consts.RIO_PREFIX + "i++) {\n");
      int ct = 0;
      for (Iterator<JField<JavaType>> i = fields.iterator(); i.hasNext();) {
        JField<JavaType> jf = i.next();
        String name = jf.getName();
        JavaType type = jf.getType();
        ct++;
        if (1 != ct) {
          cb.append("else ");
        }
        cb.append("if (" + ct + " == " + Consts.RTI_FILTER_FIELDS + "[" +
            Consts.RIO_PREFIX + "i]) {\n");
        type.genReadMethod(cb, name, name, false);
        cb.append("}\n");
      }
      if (0 != ct) {
        cb.append("else {\n");
        cb.append("java.util.ArrayList<"
                + "org.apache.hadoop.record.meta.FieldTypeInfo> typeInfos = "
                + "(java.util.ArrayList<"
                + "org.apache.hadoop.record.meta.FieldTypeInfo>)"
                + "(" + Consts.RTI_FILTER + ".getFieldTypeInfos());\n");
        cb.append("org.apache.hadoop.record.meta.Utils.skip(" + 
            Consts.RECORD_INPUT + ", " + "typeInfos.get(" + Consts.RIO_PREFIX + 
            "i).getFieldID(), typeInfos.get(" + 
            Consts.RIO_PREFIX + "i).getTypeID());\n");
        cb.append("}\n");
      }
      cb.append("}\n");
      cb.append(Consts.RECORD_INPUT + ".endRecord(" + Consts.TAG+");\n");
      cb.append("}\n");

      // compareTo()
      cb.append("public int compareTo (final Object " + Consts.RIO_PREFIX + 
          "peer_) throws ClassCastException {\n");
      cb.append("if (!(" + Consts.RIO_PREFIX + "peer_ instanceof "+name+")) {\n");
      cb.append("throw new ClassCastException(\"Comparing different types of records.\");\n");
      cb.append("}\n");
      cb.append(name+" " + Consts.RIO_PREFIX + "peer = ("+name+") " + 
          Consts.RIO_PREFIX + "peer_;\n");
      cb.append("int " + Consts.RIO_PREFIX + "ret = 0;\n");
      for (Iterator<JField<JavaType>> i = fields.iterator(); i.hasNext();) {
        JField<JavaType> jf = i.next();
        String name = jf.getName();
        JavaType type = jf.getType();
        type.genCompareTo(cb, name, Consts.RIO_PREFIX + "peer."+name);
        cb.append("if (" + Consts.RIO_PREFIX + "ret != 0) return " + 
            Consts.RIO_PREFIX + "ret;\n");
      }
      cb.append("return " + Consts.RIO_PREFIX + "ret;\n");
      cb.append("}\n");
      
      // equals()
      cb.append("public boolean equals(final Object " + Consts.RIO_PREFIX + 
          "peer_) {\n");
      cb.append("if (!(" + Consts.RIO_PREFIX + "peer_ instanceof "+name+")) {\n");
      cb.append("return false;\n");
      cb.append("}\n");
      cb.append("if (" + Consts.RIO_PREFIX + "peer_ == this) {\n");
      cb.append("return true;\n");
      cb.append("}\n");
      cb.append(name+" " + Consts.RIO_PREFIX + "peer = ("+name+") " + 
          Consts.RIO_PREFIX + "peer_;\n");
      cb.append("boolean " + Consts.RIO_PREFIX + "ret = false;\n");
      for (Iterator<JField<JavaType>> i = fields.iterator(); i.hasNext();) {
        JField<JavaType> jf = i.next();
        String name = jf.getName();
        JavaType type = jf.getType();
        type.genEquals(cb, name, Consts.RIO_PREFIX + "peer."+name);
        cb.append("if (!" + Consts.RIO_PREFIX + "ret) return " + 
            Consts.RIO_PREFIX + "ret;\n");
      }
      cb.append("return " + Consts.RIO_PREFIX + "ret;\n");
      cb.append("}\n");

      // clone()
      cb.append("public Object clone() throws CloneNotSupportedException {\n");
      cb.append(name+" " + Consts.RIO_PREFIX + "other = new "+name+"();\n");
      for (Iterator<JField<JavaType>> i = fields.iterator(); i.hasNext();) {
        JField<JavaType> jf = i.next();
        String name = jf.getName();
        JavaType type = jf.getType();
        type.genClone(cb, name);
      }
      cb.append("return " + Consts.RIO_PREFIX + "other;\n");
      cb.append("}\n");
      
      cb.append("public int hashCode() {\n");
      cb.append("int " + Consts.RIO_PREFIX + "result = 17;\n");
      cb.append("int " + Consts.RIO_PREFIX + "ret;\n");
      for (Iterator<JField<JavaType>> i = fields.iterator(); i.hasNext();) {
        JField<JavaType> jf = i.next();
        String name = jf.getName();
        JavaType type = jf.getType();
        type.genHashCode(cb, name);
        cb.append(Consts.RIO_PREFIX + "result = 37*" + Consts.RIO_PREFIX + 
            "result + " + Consts.RIO_PREFIX + "ret;\n");
      }
      cb.append("return " + Consts.RIO_PREFIX + "result;\n");
      cb.append("}\n");
      
      cb.append("public static String signature() {\n");
      cb.append("return \""+getSignature()+"\";\n");
      cb.append("}\n");
      
      cb.append("public static class Comparator extends"+
                " org.apache.hadoop.record.RecordComparator {\n");
      cb.append("public Comparator() {\n");
      cb.append("super("+name+".class);\n");
      cb.append("}\n");
      
      cb.append("static public int slurpRaw(byte[] b, int s, int l) {\n");
      cb.append("try {\n");
      cb.append("int os = s;\n");
      for (Iterator<JField<JavaType>> i = fields.iterator(); i.hasNext();) {
        JField<JavaType> jf = i.next();
        String name = jf.getName();
        JavaType type = jf.getType();
        type.genSlurpBytes(cb, "b","s","l");
      }
      cb.append("return (os - s);\n");
      cb.append("} catch(java.io.IOException e) {\n");
      cb.append("throw new RuntimeException(e);\n");
      cb.append("}\n");
      cb.append("}\n");
      
      cb.append("static public int compareRaw(byte[] b1, int s1, int l1,\n");
      cb.append("                             byte[] b2, int s2, int l2) {\n");
      cb.append("try {\n");
      cb.append("int os1 = s1;\n");
      for (Iterator<JField<JavaType>> i = fields.iterator(); i.hasNext();) {
        JField<JavaType> jf = i.next();
        String name = jf.getName();
        JavaType type = jf.getType();
        type.genCompareBytes(cb);
      }
      cb.append("return (os1 - s1);\n");
      cb.append("} catch(java.io.IOException e) {\n");
      cb.append("throw new RuntimeException(e);\n");
      cb.append("}\n");
      cb.append("}\n");
      cb.append("public int compare(byte[] b1, int s1, int l1,\n");
      cb.append("                   byte[] b2, int s2, int l2) {\n");
      cb.append("int ret = compareRaw(b1,s1,l1,b2,s2,l2);\n");
      cb.append("return (ret == -1)? -1 : ((ret==0)? 1 : 0);");
      cb.append("}\n");
      cb.append("}\n\n");
      cb.append("static {\n");
      cb.append("org.apache.hadoop.record.RecordComparator.define("
                +name+".class, new Comparator());\n");
      cb.append("}\n");
      cb.append("}\n");

      try (Writer jj = new FileWriterWithEncoding(jfile, Charsets.UTF_8)) {
        jj.write(cb.toString());
      }
    }
  }
  
  class CppRecord extends CppCompType {
    
    private String fullName;
    private String name;
    private String module;
    private ArrayList<JField<CppType>> fields = 
      new ArrayList<JField<CppType>>();
    
    CppRecord(String name, ArrayList<JField<JType>> flist) {
      super(name.replaceAll("\\.","::"));
      this.fullName = name.replaceAll("\\.", "::");
      int idx = name.lastIndexOf('.');
      this.name = name.substring(idx+1);
      this.module = name.substring(0, idx).replaceAll("\\.", "::");
      for (Iterator<JField<JType>> iter = flist.iterator(); iter.hasNext();) {
        JField<JType> f = iter.next();
        fields.add(new JField<CppType>(f.getName(), f.getType().getCppType()));
      }
    }
    
    @Override
    String getTypeIDObjectString() {
      return "new ::hadoop::StructTypeID(" + 
      fullName + "::getTypeInfo().getFieldTypeInfos())";
    }

    String genDecl(String fname) {
      return "  "+name+" "+fname+";\n";
    }
    
    @Override
    void genSetRTIFilter(CodeBuffer cb) {
      // we set the RTI filter here
      cb.append(fullName + "::setTypeFilter(rti.getNestedStructTypeInfo(\""+
          name + "\"));\n");
    }

    void genSetupRTIFields(CodeBuffer cb) {
      cb.append("void " + fullName + "::setupRtiFields() {\n");
      cb.append("if (NULL == p" + Consts.RTI_FILTER + ") return;\n");
      cb.append("if (NULL != p" + Consts.RTI_FILTER_FIELDS + ") return;\n");
      cb.append("p" + Consts.RTI_FILTER_FIELDS + " = new int[p" + 
          Consts.RTI_FILTER + "->getFieldTypeInfos().size()];\n");
      cb.append("for (unsigned int " + Consts.RIO_PREFIX + "i=0; " + 
          Consts.RIO_PREFIX + "i<p" + Consts.RTI_FILTER + 
          "->getFieldTypeInfos().size(); " + Consts.RIO_PREFIX + "i++) {\n");
      cb.append("p" + Consts.RTI_FILTER_FIELDS + "[" + Consts.RIO_PREFIX + 
          "i] = 0;\n");
      cb.append("}\n");
      cb.append("for (unsigned int " + Consts.RIO_PREFIX + "i=0; " + 
          Consts.RIO_PREFIX + "i<p" + Consts.RTI_FILTER + 
          "->getFieldTypeInfos().size(); " + Consts.RIO_PREFIX + "i++) {\n");
      cb.append("for (unsigned int " + Consts.RIO_PREFIX + "j=0; " + 
          Consts.RIO_PREFIX + "j<p" + Consts.RTI_VAR + 
          "->getFieldTypeInfos().size(); " + Consts.RIO_PREFIX + "j++) {\n");
      cb.append("if (*(p" + Consts.RTI_FILTER + "->getFieldTypeInfos()[" + 
          Consts.RIO_PREFIX + "i]) == *(p" + Consts.RTI_VAR + 
          "->getFieldTypeInfos()[" + Consts.RIO_PREFIX + "j])) {\n");
      cb.append("p" + Consts.RTI_FILTER_FIELDS + "[" + Consts.RIO_PREFIX + 
          "i] = " + Consts.RIO_PREFIX + "j+1;\n");
      cb.append("break;\n");
      cb.append("}\n");
      cb.append("}\n");
      cb.append("}\n");
      cb.append("}\n");
    }
    
    void genCode(Writer hh, Writer cc, ArrayList<String> options)
      throws IOException {
      CodeBuffer hb = new CodeBuffer();
      
      String[] ns = module.split("::");
      for (int i = 0; i < ns.length; i++) {
        hb.append("namespace "+ns[i]+" {\n");
      }
      
      hb.append("class "+name+" : public ::hadoop::Record {\n");
      hb.append("private:\n");
      
      for (Iterator<JField<CppType>> i = fields.iterator(); i.hasNext();) {
        JField<CppType> jf = i.next();
        String name = jf.getName();
        CppType type = jf.getType();
        type.genDecl(hb, name);
      }
      
      // type info vars
      hb.append("static ::hadoop::RecordTypeInfo* p" + Consts.RTI_VAR + ";\n");
      hb.append("static ::hadoop::RecordTypeInfo* p" + Consts.RTI_FILTER + ";\n");
      hb.append("static int* p" + Consts.RTI_FILTER_FIELDS + ";\n");
      hb.append("static ::hadoop::RecordTypeInfo* setupTypeInfo();\n");
      hb.append("static void setupRtiFields();\n");
      hb.append("virtual void deserializeWithoutFilter(::hadoop::IArchive& " + 
          Consts.RECORD_INPUT + ", const char* " + Consts.TAG + ");\n");
      hb.append("public:\n");
      hb.append("static const ::hadoop::RecordTypeInfo& getTypeInfo() " +
          "{return *p" + Consts.RTI_VAR + ";}\n");
      hb.append("static void setTypeFilter(const ::hadoop::RecordTypeInfo& rti);\n");
      hb.append("static void setTypeFilter(const ::hadoop::RecordTypeInfo* prti);\n");
      hb.append("virtual void serialize(::hadoop::OArchive& " + 
          Consts.RECORD_OUTPUT + ", const char* " + Consts.TAG + ") const;\n");
      hb.append("virtual void deserialize(::hadoop::IArchive& " + 
          Consts.RECORD_INPUT + ", const char* " + Consts.TAG + ");\n");
      hb.append("virtual const ::std::string& type() const;\n");
      hb.append("virtual const ::std::string& signature() const;\n");
      hb.append("virtual bool operator<(const "+name+"& peer_) const;\n");
      hb.append("virtual bool operator==(const "+name+"& peer_) const;\n");
      hb.append("virtual ~"+name+"() {};\n");
      for (Iterator<JField<CppType>> i = fields.iterator(); i.hasNext();) {
        JField<CppType> jf = i.next();
        String name = jf.getName();
        CppType type = jf.getType();
        type.genGetSet(hb, name);
      }
      hb.append("}; // end record "+name+"\n");
      for (int i=ns.length-1; i>=0; i--) {
        hb.append("} // end namespace "+ns[i]+"\n");
      }
      
      hh.write(hb.toString());
      
      CodeBuffer cb = new CodeBuffer();

      // initialize type info vars
      cb.append("::hadoop::RecordTypeInfo* " + fullName + "::p" + 
          Consts.RTI_VAR + " = " + fullName + "::setupTypeInfo();\n");
      cb.append("::hadoop::RecordTypeInfo* " + fullName + "::p" + 
          Consts.RTI_FILTER + " = NULL;\n");
      cb.append("int* " + fullName + "::p" + 
          Consts.RTI_FILTER_FIELDS + " = NULL;\n\n");

      // setupTypeInfo()
      cb.append("::hadoop::RecordTypeInfo* "+fullName+"::setupTypeInfo() {\n");
      cb.append("::hadoop::RecordTypeInfo* p = new ::hadoop::RecordTypeInfo(\"" + 
          name + "\");\n");
      for (Iterator<JField<CppType>> i = fields.iterator(); i.hasNext();) {
        JField<CppType> jf = i.next();
        String name = jf.getName();
        CppType type = jf.getType();
        type.genStaticTypeInfo(cb, name);
      }
      cb.append("return p;\n");
      cb.append("}\n");

      // setTypeFilter()
      cb.append("void "+fullName+"::setTypeFilter(const " +
          "::hadoop::RecordTypeInfo& rti) {\n");
      cb.append("if (NULL != p" + Consts.RTI_FILTER + ") {\n");
      cb.append("delete p" + Consts.RTI_FILTER + ";\n");
      cb.append("}\n");
      cb.append("p" + Consts.RTI_FILTER + " = new ::hadoop::RecordTypeInfo(rti);\n");
      cb.append("if (NULL != p" + Consts.RTI_FILTER_FIELDS + ") {\n");
      cb.append("delete p" + Consts.RTI_FILTER_FIELDS + ";\n");
      cb.append("}\n");
      cb.append("p" + Consts.RTI_FILTER_FIELDS + " = NULL;\n");
      // set RTIFilter for nested structs. We may end up with multiple lines that 
      // do the same thing, if the same struct is nested in more than one field, 
      // but that's OK. 
      for (Iterator<JField<CppType>> i = fields.iterator(); i.hasNext();) {
        JField<CppType> jf = i.next();
        CppType type = jf.getType();
        type.genSetRTIFilter(cb);
      }
      cb.append("}\n");
      
      // setTypeFilter()
      cb.append("void "+fullName+"::setTypeFilter(const " +
          "::hadoop::RecordTypeInfo* prti) {\n");
      cb.append("if (NULL != prti) {\n");
      cb.append("setTypeFilter(*prti);\n");
      cb.append("}\n");
      cb.append("}\n");

      // setupRtiFields()
      genSetupRTIFields(cb);

      // serialize()
      cb.append("void "+fullName+"::serialize(::hadoop::OArchive& " + 
          Consts.RECORD_OUTPUT + ", const char* " + Consts.TAG + ") const {\n");
      cb.append(Consts.RECORD_OUTPUT + ".startRecord(*this," + 
          Consts.TAG + ");\n");
      for (Iterator<JField<CppType>> i = fields.iterator(); i.hasNext();) {
        JField<CppType> jf = i.next();
        String name = jf.getName();
        CppType type = jf.getType();
        if (type instanceof JBuffer.CppBuffer) {
          cb.append(Consts.RECORD_OUTPUT + ".serialize("+name+","+name+
              ".length(),\""+name+"\");\n");
        } else {
          cb.append(Consts.RECORD_OUTPUT + ".serialize("+name+",\""+
              name+"\");\n");
        }
      }
      cb.append(Consts.RECORD_OUTPUT + ".endRecord(*this," + Consts.TAG + ");\n");
      cb.append("return;\n");
      cb.append("}\n");
      
      // deserializeWithoutFilter()
      cb.append("void "+fullName+"::deserializeWithoutFilter(::hadoop::IArchive& " +
          Consts.RECORD_INPUT + ", const char* " + Consts.TAG + ") {\n");
      cb.append(Consts.RECORD_INPUT + ".startRecord(*this," + 
          Consts.TAG + ");\n");
      for (Iterator<JField<CppType>> i = fields.iterator(); i.hasNext();) {
        JField<CppType> jf = i.next();
        String name = jf.getName();
        CppType type = jf.getType();
        if (type instanceof JBuffer.CppBuffer) {
          cb.append("{\nsize_t len=0; " + Consts.RECORD_INPUT + ".deserialize("+
              name+",len,\""+name+"\");\n}\n");
        } else {
          cb.append(Consts.RECORD_INPUT + ".deserialize("+name+",\""+
              name+"\");\n");
        }
      }
      cb.append(Consts.RECORD_INPUT + ".endRecord(*this," + Consts.TAG + ");\n");
      cb.append("return;\n");
      cb.append("}\n");
      
      // deserialize()
      cb.append("void "+fullName+"::deserialize(::hadoop::IArchive& " +
          Consts.RECORD_INPUT + ", const char* " + Consts.TAG + ") {\n");
      cb.append("if (NULL == p" + Consts.RTI_FILTER + ") {\n");
      cb.append("deserializeWithoutFilter(" + Consts.RECORD_INPUT + ", " + 
          Consts.TAG + ");\n");
      cb.append("return;\n");
      cb.append("}\n");
      cb.append("// if we're here, we need to read based on version info\n");
      cb.append(Consts.RECORD_INPUT + ".startRecord(*this," + 
          Consts.TAG + ");\n");
      cb.append("setupRtiFields();\n");
      cb.append("for (unsigned int " + Consts.RIO_PREFIX + "i=0; " + 
          Consts.RIO_PREFIX + "i<p" + Consts.RTI_FILTER + 
          "->getFieldTypeInfos().size(); " + Consts.RIO_PREFIX + "i++) {\n");
      int ct = 0;
      for (Iterator<JField<CppType>> i = fields.iterator(); i.hasNext();) {
        JField<CppType> jf = i.next();
        String name = jf.getName();
        CppType type = jf.getType();
        ct++;
        if (1 != ct) {
          cb.append("else ");
        }
        cb.append("if (" + ct + " == p" + Consts.RTI_FILTER_FIELDS + "[" +
            Consts.RIO_PREFIX + "i]) {\n");
        if (type instanceof JBuffer.CppBuffer) {
          cb.append("{\nsize_t len=0; " + Consts.RECORD_INPUT + ".deserialize("+
              name+",len,\""+name+"\");\n}\n");
        } else {
          cb.append(Consts.RECORD_INPUT + ".deserialize("+name+",\""+
              name+"\");\n");
        }
        cb.append("}\n");
      }
      if (0 != ct) {
        cb.append("else {\n");
        cb.append("const std::vector< ::hadoop::FieldTypeInfo* >& typeInfos = p" + 
            Consts.RTI_FILTER + "->getFieldTypeInfos();\n");
        cb.append("::hadoop::Utils::skip(" + Consts.RECORD_INPUT + 
            ", typeInfos[" + Consts.RIO_PREFIX + "i]->getFieldID()->c_str()" + 
            ", *(typeInfos[" + Consts.RIO_PREFIX + "i]->getTypeID()));\n");
        cb.append("}\n");
      }
      cb.append("}\n");
      cb.append(Consts.RECORD_INPUT + ".endRecord(*this, " + Consts.TAG+");\n");
      cb.append("}\n");

      // operator <
      cb.append("bool "+fullName+"::operator< (const "+fullName+"& peer_) const {\n");
      cb.append("return (1\n");
      for (Iterator<JField<CppType>> i = fields.iterator(); i.hasNext();) {
        JField<CppType> jf = i.next();
        String name = jf.getName();
        cb.append("&& ("+name+" < peer_."+name+")\n");
      }
      cb.append(");\n");
      cb.append("}\n");
      
      cb.append("bool "+fullName+"::operator== (const "+fullName+"& peer_) const {\n");
      cb.append("return (1\n");
      for (Iterator<JField<CppType>> i = fields.iterator(); i.hasNext();) {
        JField<CppType> jf = i.next();
        String name = jf.getName();
        cb.append("&& ("+name+" == peer_."+name+")\n");
      }
      cb.append(");\n");
      cb.append("}\n");
      
      cb.append("const ::std::string&"+fullName+"::type() const {\n");
      cb.append("static const ::std::string type_(\""+name+"\");\n");
      cb.append("return type_;\n");
      cb.append("}\n");
      
      cb.append("const ::std::string&"+fullName+"::signature() const {\n");
      cb.append("static const ::std::string sig_(\""+getSignature()+"\");\n");
      cb.append("return sig_;\n");
      cb.append("}\n");
      
      cc.write(cb.toString());
    }
  }
  
  class CRecord extends CCompType {
    
  }
  
  private String signature;
  
  /**
   * Creates a new instance of JRecord
   */
  public JRecord(String name, ArrayList<JField<JType>> flist) {
    setJavaType(new JavaRecord(name, flist));
    setCppType(new CppRecord(name, flist));
    setCType(new CRecord());
    // precompute signature
    int idx = name.lastIndexOf('.');
    String recName = name.substring(idx+1);
    StringBuilder sb = new StringBuilder();
    sb.append("L").append(recName).append("(");
    for (Iterator<JField<JType>> i = flist.iterator(); i.hasNext();) {
      String s = i.next().getType().getSignature();
      sb.append(s);
    }
    sb.append(")");
    signature = sb.toString();
  }
  
  @Override
  String getSignature() {
    return signature;
  }
  
  void genCppCode(Writer hh, Writer cc, ArrayList<String> options)
    throws IOException {
    ((CppRecord)getCppType()).genCode(hh, cc, options);
  }
  
  void genJavaCode(String destDir, ArrayList<String> options)
    throws IOException {
    ((JavaRecord)getJavaType()).genCode(destDir, options);
  }
}
