# Copyright 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Generates JS source files from a mojom.Module."""

import os
import mojom
import mojom_pack
import mojom_generator

from functools import partial
from template_expander import UseJinja

_kind_to_default_value = {
  mojom.BOOL:    "false",
  mojom.INT8:    "0",
  mojom.UINT8:   "0",
  mojom.INT16:   "0",
  mojom.UINT16:  "0",
  mojom.INT32:   "0",
  mojom.UINT32:  "0",
  mojom.FLOAT:   "0",
  mojom.HANDLE:  "core.kInvalidHandle",
  mojom.MSGPIPE: "core.kInvalidHandle",
  mojom.INT64:   "0",
  mojom.UINT64:  "0",
  mojom.DOUBLE:  "0",
  mojom.STRING:  '""',
}


def DefaultValue(field):
  if field.default:
    return field.default
  if field.kind in mojom.PRIMITIVES:
    return _kind_to_default_value[field.kind]
  if isinstance(field.kind, mojom.Struct):
    return "null";
  if isinstance(field.kind, mojom.Array):
    return "[]";


def PayloadSize(packed):
  packed_fields = packed.packed_fields
  if not packed_fields:
    return 0;
  last_field = packed_fields[-1]
  offset = last_field.offset + last_field.size
  pad = mojom_pack.GetPad(offset, 8)
  return offset + pad;


_kind_to_javascript_type = {
  mojom.BOOL:    "codec.Uint8",
  mojom.INT8:    "codec.Int8",
  mojom.UINT8:   "codec.Uint8",
  mojom.INT16:   "codec.Int16",
  mojom.UINT16:  "codec.Uint16",
  mojom.INT32:   "codec.Int32",
  mojom.UINT32:  "codec.Uint32",
  mojom.FLOAT:   "codec.Float",
  mojom.HANDLE:  "codec.Handle",
  mojom.MSGPIPE: "codec.Handle",
  mojom.INT64:   "codec.Int64",
  mojom.UINT64:  "codec.Uint64",
  mojom.DOUBLE:  "codec.Double",
  mojom.STRING:  "codec.String",
}


def GetJavaScriptType(kind):
  if kind in mojom.PRIMITIVES:
    return _kind_to_javascript_type[kind]
  if isinstance(kind, mojom.Struct):
    return "new codec.PointerTo(%s)" % GetJavaScriptType(kind.name)
  if isinstance(kind, mojom.Array):
    return "new codec.ArrayOf(%s)" % GetJavaScriptType(kind.kind)
  return kind


_kind_to_decode_snippet = {
  mojom.BOOL:    "read8() & 1",
  mojom.INT8:    "read8()",
  mojom.UINT8:   "read8()",
  mojom.INT16:   "read16()",
  mojom.UINT16:  "read16()",
  mojom.INT32:   "read32()",
  mojom.UINT32:  "read32()",
  mojom.FLOAT:   "decodeFloat()",
  mojom.HANDLE:  "decodeHandle()",
  mojom.MSGPIPE: "decodeHandle()",
  mojom.INT64:   "read64()",
  mojom.UINT64:  "read64()",
  mojom.DOUBLE:  "decodeDouble()",
  mojom.STRING:  "decodeStringPointer()",
}


def DecodeSnippet(kind):
  if kind in mojom.PRIMITIVES:
    return _kind_to_decode_snippet[kind]
  if isinstance(kind, mojom.Struct):
    return "decodeStructPointer(%s)" % GetJavaScriptType(kind.name);
  if isinstance(kind, mojom.Array):
    return "decodeArrayPointer(%s)" % GetJavaScriptType(kind.kind);


_kind_to_encode_snippet = {
  mojom.BOOL:    "write8(1 & ",
  mojom.INT8:    "write8(",
  mojom.UINT8:   "write8(",
  mojom.INT16:   "write16(",
  mojom.UINT16:  "write16(",
  mojom.INT32:   "write32(",
  mojom.UINT32:  "write32(",
  mojom.FLOAT:   "encodeFloat(",
  mojom.HANDLE:  "encodeHandle(",
  mojom.MSGPIPE: "encodeHandle(",
  mojom.INT64:   "write64(",
  mojom.UINT64:  "write64(",
  mojom.DOUBLE:  "encodeDouble(",
  mojom.STRING:  "encodeStringPointer(",
}


def EncodeSnippet(kind):
  if kind in mojom.PRIMITIVES:
    return _kind_to_encode_snippet[kind]
  if isinstance(kind, mojom.Struct):
    return "encodeStructPointer(%s, " % GetJavaScriptType(kind.name);
  if isinstance(kind, mojom.Array):
    return "encodeArrayPointer(%s, " % GetJavaScriptType(kind.kind);


def GetStructInfo(exported, struct):
  packed_struct = mojom_pack.PackedStruct(struct)
  return {
    "name": struct.name,
    "packed": packed_struct,
    "bytes": mojom_pack.GetByteLayout(packed_struct),
    "exported": exported,
  }


class JSGenerator(mojom_generator.Generator):
  filters = {
    "default_value": DefaultValue,
    "payload_size": PayloadSize,
    "decode_snippet": DecodeSnippet,
    "encode_snippet": EncodeSnippet,
    "stylize_method": mojom_generator.StudlyCapsToCamel,
  }

  def GetStructsFromMethods(self):
    result = []
    for interface in self.module.interfaces:
      for method in interface.methods:
        result.append(mojom_generator.GetStructFromMethod(interface, method))
    return map(partial(GetStructInfo, False), result)

  def GetStructs(self):
    return map(partial(GetStructInfo, True), self.module.structs)

  @UseJinja("js_templates/module.js.tmpl", filters=filters)
  def GenerateModule(self):
    return {
      "structs": self.GetStructs() + self.GetStructsFromMethods(),
      "interfaces": self.module.interfaces,
    }

  def Write(self, contents):
    if self.output_dir is None:
      print contents
      return
    filename = "%s.js" % self.module.name
    with open(os.path.join(self.output_dir, filename), "w+") as f:
      f.write(contents)

  def GenerateFiles(self):
    self.Write(self.GenerateModule())
