#!/usr/bin/env python

#
# Copyright (C) 2011 The Android Open Source Project
#
# 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.
#

import os
import sys

hFileTemplate = """/**
 * This file is auto-generated by platform/system/media/mca/structgen.py! Do NOT modify!
 **/

#ifndef %s
#define %s

%s

#endif // %s
"""

jniFileTemplate = """/**
 * This file is auto-generated by platform/system/media/mca/structgen.py! Do NOT modify!
 **/

#include <stdint.h>
#include "native/%s.h"

#ifdef __cplusplus
extern "C" {
#endif

#include "jni.h"

// Helper functions ////////////////////////////////////////////////////////////////////////////////
%s* Get%sAtIndex(JNIEnv* env, jobject buffer, int index) {
  jclass base_class = (*env)->FindClass(env, "android/filterfw/core/NativeBuffer");
  jfieldID ptr_field = (*env)->GetFieldID(env, base_class, "mDataPointer", "J");
  uintptr_t data_ptr = (*env)->GetLongField(env, buffer, ptr_field);
  %s* array = (%s*)data_ptr;
  (*env)->DeleteLocalRef(env, base_class);
  return &array[index];
}

// Declarations ////////////////////////////////////////////////////////////////////////////////////
JNIEXPORT jint JNICALL
Java_%s_getElementSize(JNIEnv* env, jobject thiz);

%s

#ifdef __cplusplus
}
#endif

// Implementation //////////////////////////////////////////////////////////////////////////////////
jint Java_%s_getElementSize(JNIEnv* env, jobject thiz) {
  return sizeof(%s);
}

%s
"""

javaFileTemplate = """/**
 * This file is auto-generated by platform/system/media/mca/structgen.py! Do NOT modify!
 **/

package %s;

import android.filterfw.core.NativeBuffer;

%s
"""


def ToJavaName(cname, start_upper_at = 1):
  lower = cname.split("_")
  upper = [c.title() for c in lower]
  return "".join(lower[:start_upper_at] + upper[start_upper_at:])

def ToJNIPackage(package, jclassname):
  return "%s_%s" % (package.replace(".", "_"), jclassname)

def ToMacroDefName(cname, pname):
  return "%s_%s" % (pname.replace(".", "_").upper(), cname.upper())

class ParseError:
  def __init__(self, lineno, message):
    self.lineno = lineno
    self.message = message

  def __str__(self):
    return "On line %d: %s" % (self.lineno, self.message)

class FieldType_BasePOD:
  def __init__(self, name, structname, jclassname, package, javatype, ctype, jtype, defval):
    self.name = name
    self.structname = structname
    self.jclassname = jclassname
    self.package = package
    self.javatype = javatype
    self.ctype = ctype
    self.jtype = jtype
    self.defval = defval

  def cString(self):
    return "  %s %s;" % (self.ctype, self.name)

  def javaGetter(self):
    return "    public %s get%s(int index) {\n"\
           "        assertReadable();\n"\
           "        return nativeGet%s(index);\n"\
           "    }" % (self.javatype, ToJavaName(self.name, 0), ToJavaName(self.name, 0))

  def javaSetter(self):
    return "    public void set%s(int index, %s value) {\n"\
           "        assertWritable();\n"\
           "        nativeSet%s(index, value);\n"\
           "    }" % (ToJavaName(self.name, 0), self.javatype, ToJavaName(self.name, 0))

  def javaNativeGetter(self):
    return "    private native %s nativeGet%s(int index);"\
           % (self.javatype, ToJavaName(self.name, 0))

  def javaNativeSetter(self):
    return "    private native boolean nativeSet%s(int index, %s value);"\
           % (ToJavaName(self.name, 0), self.javatype)

  def jniGetterDefString(self):
    return "JNIEXPORT %s JNICALL\n" \
           "Java_%s_nativeGet%s(JNIEnv* env, jobject thiz, jint index);" \
           % (self.jtype, ToJNIPackage(self.package, self.jclassname), ToJavaName(self.name, 0))

  def jniGetterImplString(self):
    return \
      "%s Java_%s_nativeGet%s(JNIEnv* env, jobject thiz, jint index) {\n"\
      "  %s* instance = Get%sAtIndex(env, thiz, index);\n"\
      "  return instance ? instance->%s : %s;\n"\
      "}\n" % (self.jtype, ToJNIPackage(self.package, self.jclassname), ToJavaName(self.name, 0),\
               self.structname, self.structname, self.name, self.defval)

  def jniSetterDefString(self):
    return "JNIEXPORT jboolean JNICALL\n" \
           "Java_%s_nativeSet%s(JNIEnv* env, jobject thiz, jint index, %s value);" \
           % (ToJNIPackage(self.package, self.jclassname), ToJavaName(self.name, 0), self.jtype)

  def jniSetterImplString(self):
    return \
      "jboolean Java_%s_nativeSet%s(JNIEnv* env, jobject thiz, jint index, %s value) {\n"\
      "  %s* instance = Get%sAtIndex(env, thiz, index);\n"\
      "  if (instance) {\n"\
      "    instance->%s = value;\n"\
      "    return JNI_TRUE;\n"\
      "  }\n"\
      "  return JNI_FALSE;\n"\
      "}\n" % (ToJNIPackage(self.package, self.jclassname), ToJavaName(self.name, 0),\
               self.jtype, self.structname, self.structname, self.name)

class FieldType_Float(FieldType_BasePOD):
  def __init__(self, name, structname, jclassname, package):
    FieldType_BasePOD.__init__(self, name, structname, jclassname, package, "float", "float", "jfloat", "0.0")

class FieldType_Int(FieldType_BasePOD):
  def __init__(self, name, structname, jclassname, package):
    FieldType_BasePOD.__init__(self, name, structname, jclassname, package, "int", "int", "jint", "0")

class FieldType_Long(FieldType_BasePOD):
  def __init__(self, name, structname, jclassname, package):
    FieldType_BasePOD.__init__(self, name, structname, jclassname, package, "long", "long long", "jlong", "0")

class StructSpec:

  def parseTextFile(self, filepath):
    # Init
    self.name = None
    self.package = None
    self.fields = []
    self.structname = None
    self.jclassname = None
    self.libname = None

    # Open the file
    txtfile = open(filepath)

    # Parse it line by line
    lineno = 0
    for line in txtfile:
      # Split line into components
      linecomps = line.split()
      if len(linecomps) == 0:
        continue

      # Execute command
      cmd = linecomps[0]
      if cmd == "@name":
        self.commandArgAssert(linecomps, 1, lineno)
        self.name = linecomps[1]
        if not self.structname:
          self.structname = self.name
        if not self.jclassname:
          self.jclassname = self.name
      elif cmd == "@package":
        self.commandArgAssert(linecomps, 1, lineno)
        self.package = linecomps[1]
      elif cmd == "@libname":
        self.commandArgAssert(linecomps, 1, lineno)
        self.libname = linecomps[1]
      elif cmd == "@structname":
        self.commandArgAssert(linecomps, 1, lineno)
        self.structname = linecomps[1]
      elif cmd == "@javaclassname":
        self.commandArgAssert(linecomps, 1, lineno)
        self.jclassname = linecomps[1]
      elif cmd == "@field":
        self.commandArgAssert(linecomps, 2, lineno)
        typestr = linecomps[1]
        if typestr == "int":
          fieldtype = FieldType_Int(linecomps[2], self.structname, self.jclassname, self.package)
        elif typestr == "long":
          fieldtype = FieldType_Long(linecomps[2], self.structname, self.jclassname, self.package)
        elif typestr == "float":
          fieldtype = FieldType_Float(linecomps[2], self.structname, self.jclassname, self.package)
        else:
          raise ParseError(lineno, "Unknown field type '%s'!" % typestr)
        self.fields.append(fieldtype)
      else:
        raise ParseError(lineno, "Unknown command: '%s'!" % cmd)

      lineno = lineno + 1

    # Make sure we have all required info
    if not self.name:
      raise ParseError(lineno, "Required field '@name' missing!")
    elif not self.package:
      raise ParseError(lineno, "Required field '@package' missing!")
    elif not self.libname:
      raise ParseError(lineno, "Required field '@libname' missing!")

    # Normalize values
    if self.libname[:3] == "lib":
      self.libname = self.libname[3:]

  def commandArgAssert(self, linecomps, expectedcount, lineno):
    foundcount = len(linecomps) - 1
    if foundcount < expectedcount:
      raise ParseError(lineno, "Not enough arguments specifed for command '%s'! Expected %d, " \
                       "but got only %d!" % (linecomps[0], expectedcount, foundcount))
    elif foundcount > expectedcount + 1:
      raise ParseError(lineno, "Too many arguments specifed for command '%s'! Expected %d, " \
                       "but got %d!" % (linecomps[0], expectedcount, foundcount))


  def cStructString(self):
    cfields = [f.cString() for f in self.fields]
    return "typedef struct Struct%s {\n%s\n} %s;\n" % (self.structname,\
                                                       "\n".join(cfields),\
                                                       self.structname)

  def javaClassString(self):
    jgetters = [f.javaGetter() for f in self.fields]
    jsetters = [f.javaSetter() for f in self.fields]
    jnativesetters = [f.javaNativeSetter() for f in self.fields]
    jnativegetters = [f.javaNativeGetter() for f in self.fields]
    return "public class %s extends NativeBuffer {\n\n"\
           "    public %s() {\n"\
           "        super();\n"\
           "    }\n"\
           "\n"\
           "    public %s(int count) {\n"\
           "        super(count);\n"\
           "    }\n"\
           "\n"\
           "    public native int getElementSize();\n"\
           "\n"\
           "%s\n\n"\
           "%s\n\n"\
           "%s\n\n"\
           "%s\n\n"\
           "    static {\n"\
           "        System.loadLibrary(\"%s\");\n"\
           "    }\n"\
           "\n"\
           "};\n" % (self.jclassname,\
                     self.jclassname,\
                     self.jclassname,\
                     "\n\n".join(jgetters),\
                     "\n\n".join(jsetters),\
                     "\n\n".join(jnativegetters),\
                     "\n\n".join(jnativesetters),\
                     self.libname)

  def jniDeclString(self):
    jnigetters = [f.jniGetterDefString() for f in self.fields]
    jnisetters = [f.jniSetterDefString() for f in self.fields]
    return "\n\n".join(jnigetters + jnisetters)

  def jniImplString(self):
    jnigetters = [f.jniGetterImplString() for f in self.fields]
    jnisetters = [f.jniSetterImplString() for f in self.fields]
    return "\n\n".join(jnigetters + jnisetters)

  def hFileString(self):
    defname = ToMacroDefName(self.structname, self.package)
    return hFileTemplate % (defname, defname, self.cStructString(), defname)

  def javaFileString(self):
    return javaFileTemplate % (self.package, self.javaClassString())

  def jniFileString(self):
    return jniFileTemplate % (self.structname.lower(),\
                              self.structname,\
                              self.structname,\
                              self.structname,\
                              self.structname,\
                              ToJNIPackage(self.package, self.jclassname),\
                              self.jniDeclString(),\
                              ToJNIPackage(self.package, self.jclassname),\
                              self.structname,
                              self.jniImplString())

def main(argv):
  if len(argv) != 2:
    print("Usage: %s <file.struct>" % argv[0])
    return -1

  filepath = argv[1]

  structspec = StructSpec()
  structspec.parseTextFile(filepath)

  hfilename = "%s.h" % structspec.structname.lower()
  javafilename = "%s.java" % structspec.jclassname
  jnifilename = "jni_%s.c" % structspec.structname.lower()

  javapackagepath = structspec.package.replace('.','/')

  rootdir = os.path.dirname(filepath)
  hfilepath = "%s/../native/%s" % (rootdir, hfilename)
  javafilepath = "%s/../java/%s/%s" % (rootdir, javapackagepath, javafilename)
  jnifilepath = "%s/../jni/%s" % (rootdir, jnifilename)

  hfile = open(hfilepath, 'w')
  hfile.write(structspec.hFileString())
  hfile.close()

  javafile = open(javafilepath, 'w')
  javafile.write(structspec.javaFileString())
  javafile.close()

  jnifile = open(jnifilepath, 'w')
  jnifile.write(structspec.jniFileString())
  jnifile.close()


if __name__ == "__main__":
  sys.exit(main(sys.argv))
