/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * $Id$
 ***************************************************************************/

#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <library.h>
#include <netware.h>
#include <screen.h>
#include <nks/thread.h>
#include <nks/synch.h>

#include "memory.h"
#include "memdebug.h"

typedef struct
{
  int     _errno;
  void    *twentybytes;
} libthreaddata_t;

typedef struct
{
  int         x;
  int         y;
  int         z;
  void        *tenbytes;
  NXKey_t     perthreadkey;   /* if -1, no key obtained... */
  NXMutex_t   *lock;
} libdata_t;

int         gLibId      = -1;
void        *gLibHandle = (void *) NULL;
rtag_t      gAllocTag   = (rtag_t) NULL;
NXMutex_t   *gLibLock   = (NXMutex_t *) NULL;

/* internal library function prototypes... */
int     DisposeLibraryData ( void * );
void    DisposeThreadData ( void * );
int     GetOrSetUpData ( int id, libdata_t **data, libthreaddata_t **threaddata );


int _NonAppStart( void        *NLMHandle,
                  void        *errorScreen,
                  const char  *cmdLine,
                  const char  *loadDirPath,
                  size_t      uninitializedDataLength,
                  void        *NLMFileHandle,
                  int         (*readRoutineP)( int conn,
                                               void *fileHandle, size_t offset,
                                               size_t nbytes,
                                               size_t *bytesRead,
                                               void *buffer ),
                  size_t      customDataOffset,
                  size_t      customDataSize,
                  int         messageCount,
                  const char  **messages )
{
  NX_LOCK_INFO_ALLOC(liblock, "Per-Application Data Lock", 0);
  
#ifndef __GNUC__
#pragma unused(cmdLine)
#pragma unused(loadDirPath)
#pragma unused(uninitializedDataLength)
#pragma unused(NLMFileHandle)
#pragma unused(readRoutineP)
#pragma unused(customDataOffset)
#pragma unused(customDataSize)
#pragma unused(messageCount)
#pragma unused(messages)
#endif

/*
** Here we process our command line, post errors (to the error screen),
** perform initializations and anything else we need to do before being able
** to accept calls into us. If we succeed, we return non-zero and the NetWare
** Loader will leave us up, otherwise we fail to load and get dumped.
*/
  gAllocTag = AllocateResourceTag(NLMHandle,
                                  "<library-name> memory allocations",
                                  AllocSignature);

  if (!gAllocTag) {
    OutputToScreen(errorScreen, "Unable to allocate resource tag for "
                   "library memory allocations.\n");
    return -1;
  }

  gLibId = register_library(DisposeLibraryData);

  if (gLibId < -1) {
    OutputToScreen(errorScreen, "Unable to register library with kernel.\n");
    return -1;
  }

  gLibHandle = NLMHandle;

  gLibLock = NXMutexAlloc(0, 0, &liblock);
  
  if (!gLibLock) {
    OutputToScreen(errorScreen, "Unable to allocate library data lock.\n");
    return -1;
  }

  return 0;
}

/*
** Here we clean up any resources we allocated. Resource tags is a big part
** of what we created, but NetWare doesn't ask us to free those.
*/
void _NonAppStop( void )
{
  (void) unregister_library(gLibId);
  NXMutexFree(gLibLock);
}

/*
** This function cannot be the first in the file for if the file is linked
** first, then the check-unload function's offset will be nlmname.nlm+0
** which is how to tell that there isn't one. When the check function is
** first in the linked objects, it is ambiguous. For this reason, we will
** put it inside this file after the stop function.
**
** Here we check to see if it's alright to ourselves to be unloaded. If not,
** we return a non-zero value. Right now, there isn't any reason not to allow
** it.
*/
int  _NonAppCheckUnload( void )
{
    return 0;
}

int GetOrSetUpData(int id, libdata_t **appData,
                   libthreaddata_t **threadData )
{
  int                 err;
  libdata_t           *app_data;
  libthreaddata_t *thread_data;
  NXKey_t             key;
  NX_LOCK_INFO_ALLOC(liblock, "Application Data Lock", 0);

  err         = 0;
  thread_data = (libthreaddata_t *) NULL;

/*
** Attempt to get our data for the application calling us. This is where we
** store whatever application-specific information we need to carry in support
** of calling applications.
*/
  app_data = (libdata_t *) get_app_data(id);

  if (!app_data) {
/*
** This application hasn't called us before; set up application AND per-thread
** data. Of course, just in case a thread from this same application is calling
** us simultaneously, we better lock our application data-creation mutex. We
** also need to recheck for data after we acquire the lock because WE might be
** that other thread that was too late to create the data and the first thread
** in will have created it.
*/
    NXLock(gLibLock);

    if (!(app_data = (libdata_t *) get_app_data(id))) {
      app_data = (libdata_t *) malloc(sizeof(libdata_t));

      if (app_data) {
        memset(app_data, 0, sizeof(libdata_t));
        
        app_data->tenbytes = malloc(10);
        app_data->lock     = NXMutexAlloc(0, 0, &liblock);
        
        if (!app_data->tenbytes || !app_data->lock) {
          if (app_data->lock)
            NXMutexFree(app_data->lock);
          
          free(app_data);
          app_data = (libdata_t *) NULL;
          err      = ENOMEM;
        }
        
        if (app_data) {
/*
** Here we burn in the application data that we were trying to get by calling
** get_app_data(). Next time we call the first function, we'll get this data
** we're just now setting. We also go on here to establish the per-thread data
** for the calling thread, something we'll have to do on each application
** thread the first time it calls us.
*/
          err = set_app_data(gLibId, app_data);
          
          if (err) {
            free(app_data);
            app_data = (libdata_t *) NULL;
            err      = ENOMEM;
          }
          else {
            /* create key for thread-specific data... */
            err = NXKeyCreate(DisposeThreadData, (void *) NULL, &key);
            
            if (err)                /* (no more keys left?) */
              key = -1;
            
            app_data->perthreadkey = key;
          }
        }
      }
    }
    
    NXUnlock(gLibLock);
  }

  if (app_data) {
    key = app_data->perthreadkey;
    
    if (key != -1 /* couldn't create a key? no thread data */
        && !(err = NXKeyGetValue(key, (void **) &thread_data))
        && !thread_data) {
/*
** Allocate the per-thread data for the calling thread. Regardless of whether
** there was already application data or not, this may be the first call by a
** a new thread. The fact that we allocation 20 bytes on a pointer is not very
** important, this just helps to demonstrate that we can have arbitrarily
** complex per-thread data.
*/
      thread_data = (libthreaddata_t *) malloc(sizeof(libthreaddata_t));
      
      if (thread_data) {
        thread_data->_errno      = 0;
        thread_data->twentybytes = malloc(20);
          
        if (!thread_data->twentybytes) {
          free(thread_data);
          thread_data = (libthreaddata_t *) NULL;
          err         = ENOMEM;
        }
        
        if ((err = NXKeySetValue(key, thread_data))) {
          free(thread_data->twentybytes);
          free(thread_data);
          thread_data = (libthreaddata_t *) NULL;
        }
      }
    }
  }

  if (appData)
    *appData = app_data;

  if (threadData)
    *threadData = thread_data;

  return err;
}

int DisposeLibraryData( void    *data)
{
  if (data) {
    void    *tenbytes = ((libdata_t *) data)->tenbytes;
    
    if (tenbytes)
      free(tenbytes);
    
    free(data);
  }

  return 0;
}

void DisposeThreadData(void    *data)
{
  if (data) {
    void    *twentybytes = ((libthreaddata_t *) data)->twentybytes;
    
    if (twentybytes)
      free(twentybytes);
    
    free(data);
  }
}
