/*
 * IDL Compiler
 *
 * Copyright 2004 Ove Kaaven
 * Copyright 2006 Jacek Caban for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"
#include "wine/port.h"
#include "wine/wpp.h"

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <string.h>
#include <ctype.h>

#include "windef.h"
#include "winbase.h"

#include "widl.h"
#include "utils.h"
#include "parser.h"
#include "header.h"
#include "typelib.h"
#include "widltypes.h"
#include "typelib_struct.h"
#include "typetree.h"


/* List of oleauto types that should be recognized by name.
 * (most of) these seem to be intrinsic types in mktyplib.
 * This table MUST be alphabetically sorted on the kw field.
 */
static const struct oatype {
  const char *kw;
  unsigned short vt;
} oatypes[] = {
  {"BSTR",          VT_BSTR},
  {"CURRENCY",      VT_CY},
  {"DATE",          VT_DATE},
  {"DECIMAL",       VT_DECIMAL},
  {"HRESULT",       VT_HRESULT},
  {"LPSTR",         VT_LPSTR},
  {"LPWSTR",        VT_LPWSTR},
  {"SCODE",         VT_ERROR},
  {"VARIANT",       VT_VARIANT},
  {"VARIANT_BOOL",  VT_BOOL}
};
#define KWP(p) ((const struct oatype *)(p))

static int kw_cmp_func(const void *s1, const void *s2)
{
        return strcmp(KWP(s1)->kw, KWP(s2)->kw);
}

static unsigned short builtin_vt(const type_t *t)
{
  const char *kw = t->name;
  struct oatype key;
  const struct oatype *kwp;
  key.kw = kw;
#ifdef KW_BSEARCH
  kwp = bsearch(&key, oatypes, ARRAY_SIZE(oatypes), sizeof(oatypes[0]), kw_cmp_func);
#else
  {
    unsigned int i;
    for (kwp = NULL, i = 0; i < ARRAY_SIZE(oatypes); i++)
      if (!kw_cmp_func(&key, &oatypes[i])) {
        kwp = &oatypes[i];
        break;
      }
  }
#endif
  if (kwp) {
    return kwp->vt;
  }
  if (is_string_type (t->attrs, t))
  {
    const type_t *elem_type;
    if (is_array(t))
      elem_type = type_array_get_element_type(t);
    else
      elem_type = type_pointer_get_ref_type(t);
    if (type_get_type(elem_type) == TYPE_BASIC)
    {
      switch (type_basic_get_type(elem_type))
      {
      case TYPE_BASIC_CHAR: return VT_LPSTR;
      case TYPE_BASIC_WCHAR: return VT_LPWSTR;
      default: break;
      }
    }
  }
  return 0;
}

static int match(const char*n, const char*m)
{
  if (!n) return 0;
  return !strcmp(n, m);
}

unsigned short get_type_vt(type_t *t)
{
  unsigned short vt;

  chat("get_type_vt: %p type->name %s\n", t, t->name);
  if (t->name) {
    vt = builtin_vt(t);
    if (vt) return vt;
  }

  if (type_is_alias(t) &&
        (is_attr(t->attrs, ATTR_PUBLIC) || is_attr(t->attrs, ATTR_WIREMARSHAL)))
    return VT_USERDEFINED;

  switch (type_get_type(t)) {
  case TYPE_BASIC:
    switch (type_basic_get_type(t)) {
    case TYPE_BASIC_BYTE:
      return VT_UI1;
    case TYPE_BASIC_CHAR:
    case TYPE_BASIC_INT8:
      if (type_basic_get_sign(t) > 0)
        return VT_UI1;
      else
        return VT_I1;
    case TYPE_BASIC_WCHAR:
      return VT_I2; /* mktyplib seems to parse wchar_t as short */
    case TYPE_BASIC_INT16:
      if (type_basic_get_sign(t) > 0)
        return VT_UI2;
      else
        return VT_I2;
    case TYPE_BASIC_INT:
      if (type_basic_get_sign(t) > 0)
        return VT_UINT;
      else
        return VT_INT;
    case TYPE_BASIC_INT32:
    case TYPE_BASIC_LONG:
    case TYPE_BASIC_ERROR_STATUS_T:
      if (type_basic_get_sign(t) > 0)
        return VT_UI4;
      else
        return VT_I4;
    case TYPE_BASIC_INT64:
    case TYPE_BASIC_HYPER:
      if (type_basic_get_sign(t) > 0)
        return VT_UI8;
      else
        return VT_I8;
    case TYPE_BASIC_INT3264:
      if (pointer_size == 8)
      {
        if (type_basic_get_sign(t) > 0)
          return VT_UI8;
        else
          return VT_I8;
      }
      else
      {
        if (type_basic_get_sign(t) > 0)
          return VT_UI4;
        else
          return VT_I4;
      }
    case TYPE_BASIC_FLOAT:
      return VT_R4;
    case TYPE_BASIC_DOUBLE:
      return VT_R8;
    case TYPE_BASIC_HANDLE:
      error("handles can't be used in typelibs\n");
    }
    break;

  case TYPE_POINTER:
    return VT_PTR;

  case TYPE_ARRAY:
    if (type_array_is_decl_as_ptr(t))
    {
      if (match(type_array_get_element_type(t)->name, "SAFEARRAY"))
        return VT_SAFEARRAY;
      return VT_PTR;
    }
    else
      return VT_CARRAY;

  case TYPE_INTERFACE:
    if(match(t->name, "IUnknown"))
      return VT_UNKNOWN;
    if(match(t->name, "IDispatch"))
      return VT_DISPATCH;
    return VT_USERDEFINED;

  case TYPE_ENUM:
  case TYPE_STRUCT:
  case TYPE_COCLASS:
  case TYPE_MODULE:
  case TYPE_UNION:
  case TYPE_ENCAPSULATED_UNION:
  case TYPE_RUNTIMECLASS:
    return VT_USERDEFINED;

  case TYPE_VOID:
    return VT_VOID;

  case TYPE_ALIAS:
  case TYPE_APICONTRACT:
    /* not supposed to be here */
    assert(0);
    break;

  case TYPE_FUNCTION:
    error("get_type_vt: functions not supported\n");
    break;

  case TYPE_BITFIELD:
    error("get_type_vt: bitfields not supported\n");
    break;
  }
  return 0;
}

static void tlb_read(int fd, void *buf, int count)
{
    if(read(fd, buf, count) < count)
        error("error while reading importlib.\n");
}

static void tlb_lseek(int fd, off_t offset)
{
    if(lseek(fd, offset, SEEK_SET) == -1)
        error("lseek failed\n");
}

static void msft_read_guid(int fd, MSFT_SegDir *segdir, int offset, GUID *guid)
{
    tlb_lseek(fd, segdir->pGuidTab.offset+offset);
    tlb_read(fd, guid, sizeof(GUID));
}

static void read_msft_importlib(importlib_t *importlib, int fd)
{
    MSFT_Header header;
    MSFT_SegDir segdir;
    int *typeinfo_offs;
    int i;

    importlib->allocated = 0;

    tlb_lseek(fd, 0);
    tlb_read(fd, &header, sizeof(header));

    importlib->version = header.version;

    typeinfo_offs = xmalloc(header.nrtypeinfos*sizeof(INT));
    tlb_read(fd, typeinfo_offs, header.nrtypeinfos*sizeof(INT));
    tlb_read(fd, &segdir, sizeof(segdir));

    msft_read_guid(fd, &segdir, header.posguid, &importlib->guid);

    importlib->ntypeinfos = header.nrtypeinfos;
    importlib->importinfos = xmalloc(importlib->ntypeinfos*sizeof(importinfo_t));

    for(i=0; i < importlib->ntypeinfos; i++) {
        MSFT_TypeInfoBase base;
        MSFT_NameIntro nameintro;
        int len;

        tlb_lseek(fd, sizeof(MSFT_Header) + header.nrtypeinfos*sizeof(INT) + sizeof(MSFT_SegDir)
                 + typeinfo_offs[i]);
        tlb_read(fd, &base, sizeof(base));

        importlib->importinfos[i].importlib = importlib;
        importlib->importinfos[i].flags = (base.typekind&0xf)<<24;
        importlib->importinfos[i].offset = -1;
        importlib->importinfos[i].id = i;

        if(base.posguid != -1) {
            importlib->importinfos[i].flags |= MSFT_IMPINFO_OFFSET_IS_GUID;
            msft_read_guid(fd, &segdir, base.posguid, &importlib->importinfos[i].guid);
        }
        else memset( &importlib->importinfos[i].guid, 0, sizeof(importlib->importinfos[i].guid));

        tlb_lseek(fd, segdir.pNametab.offset + base.NameOffset);
        tlb_read(fd, &nameintro, sizeof(nameintro));

        len = nameintro.namelen & 0xff;

        importlib->importinfos[i].name = xmalloc(len+1);
        tlb_read(fd, importlib->importinfos[i].name, len);
        importlib->importinfos[i].name[len] = 0;
    }

    free(typeinfo_offs);
}

static int open_typelib(const char *name)
{
    char *file_name;
    int fd;

    file_name = wpp_find_include(name, NULL);
    if(!file_name)
        return open(name, O_RDONLY | O_BINARY );

    fd = open(file_name, O_RDONLY | O_BINARY );
    free(file_name);
    return fd;
}

static void read_importlib(importlib_t *importlib)
{
    int fd;
    INT magic;

    fd = open_typelib(importlib->name);

    /* widl extension: if importlib name has no .tlb extension, try using .tlb */
    if(fd < 0) {
        const char *p = strrchr(importlib->name, '.');
        size_t len = p ? p - importlib->name : strlen(importlib->name);
        if(strcmp(importlib->name + len, ".tlb")) {
            char *tlb_name = xmalloc(len + 5);
            memcpy(tlb_name, importlib->name, len);
            strcpy(tlb_name + len, ".tlb");
            fd = open_typelib(tlb_name);
            free(tlb_name);
        }
    }

    if(fd < 0)
        error("Could not find importlib %s.\n", importlib->name);

    tlb_read(fd, &magic, sizeof(magic));

    switch(magic) {
    case MSFT_MAGIC:
        read_msft_importlib(importlib, fd);
        break;
    default:
        error("Wrong or unsupported typelib magic %x\n", magic);
    };

    close(fd);
}

void add_importlib(const char *name, typelib_t *typelib)
{
    importlib_t *importlib;

    if(!typelib) return;

    LIST_FOR_EACH_ENTRY( importlib, &typelib->importlibs, importlib_t, entry )
        if(!strcmp(name, importlib->name))
            return;

    chat("add_importlib: %s\n", name);

    importlib = xmalloc(sizeof(*importlib));
    memset( importlib, 0, sizeof(*importlib) );
    importlib->name = xstrdup(name);

    read_importlib(importlib);
    list_add_head( &typelib->importlibs, &importlib->entry );
}
