/* $Id$ */
/* 
 * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
#ifndef __PJPP_OS_HPP__
#define __PJPP_OS_HPP__

#include <pj/os.h>
#include <pj/string.h>
#include <pj++/types.hpp>
#include <pj++/pool.hpp>

class Pj_Thread;

//
// Thread API.
//
class Pj_Thread_API
{
public:
    //
    // Create a thread.
    //
    static pj_status_t create( Pj_Pool *pool, pj_thread_t **thread,
                               pj_thread_proc *proc, void *arg,
                               unsigned flags = 0,
                               const char *name = NULL,
                               pj_size_t stack_size = 0 )
    {
        return pj_thread_create(pool->pool_(), name, proc, arg, stack_size,
                                flags, thread);
    }

    //
    // Register a thread.
    //
    static pj_status_t register_this_thread( pj_thread_desc desc,
                                             pj_thread_t **thread,
                                             const char *name = NULL )
    {
        return pj_thread_register( name, desc, thread );
    }

    //
    // Get current thread.
    // Will return pj_thread_t (sorry folks, not Pj_Thread).
    //
    static pj_thread_t *this_thread()
    {
        return pj_thread_this();
    }

    //
    // Get thread name.
    //
    static const char *get_name(pj_thread_t *thread)
    {
        return pj_thread_get_name(thread);
    }

    //
    // Resume thread.
    //
    static pj_status_t resume(pj_thread_t *thread)
    {
        return pj_thread_resume(thread);
    }

    //
    // Sleep.
    //
    static pj_status_t sleep(unsigned msec)
    {
	return pj_thread_sleep(msec);
    }

    //
    // Join the specified thread.
    //
    static pj_status_t join(pj_thread_t *thread)
    {
        return pj_thread_join(thread);
    }

    //
    // Destroy thread
    //
    static pj_status_t destroy(pj_thread_t *thread)
    {
        return pj_thread_destroy(thread);
    }
};



//
// Thread object.
//
// How to use:
//  Derive a class from this class, then override main().
//
class Pj_Thread : public Pj_Object
{
public:
    enum Flags
    {
	FLAG_SUSPENDED = PJ_THREAD_SUSPENDED
    };

    //
    // Default constructor.
    //
    Pj_Thread()
        : thread_(NULL)
    {
    }

    //
    // Destroy thread.
    //
    ~Pj_Thread()
    {
        destroy();
    }

    //
    // This is the main thread function.
    //
    virtual int main() = 0;

    //
    // Start a thread.
    //
    pj_status_t create( Pj_Pool *pool, 
                        unsigned flags = 0,
                        const char *thread_name = NULL,
			pj_size_t stack_size = PJ_THREAD_DEFAULT_STACK_SIZE)
    {
        destroy();
        return Pj_Thread_API::create( pool, &thread_, &thread_proc, this,
                                      flags, thread_name, stack_size);
    }

    //
    // Get pjlib compatible thread object.
    //
    pj_thread_t *pj_thread_t_()
    {
	return thread_;
    }

    //
    // Get thread name.
    //
    const char *get_name()
    {
        return Pj_Thread_API::get_name(thread_);
    }

    //
    // Resume a suspended thread.
    //
    pj_status_t resume()
    {
        return Pj_Thread_API::resume(thread_);
    }

    //
    // Join this thread.
    //
    pj_status_t join()
    {
        return Pj_Thread_API::join(thread_);
    }

    //
    // Destroy thread.
    //
    pj_status_t destroy()
    {
        if (thread_) {
            Pj_Thread_API::destroy(thread_);
            thread_ = NULL;
        }
    }

protected:
    pj_thread_t *thread_;

    static int PJ_THREAD_FUNC thread_proc(void *obj)
    {
        Pj_Thread *thread_class = (Pj_Thread*)obj;
        return thread_class->main();
    }
};


//
// External Thread
//  (threads that were started by external means, i.e. not 
//   with Pj_Thread::create).
//
// This class will normally be defined as local variable in
// external thread's stack, normally inside thread's main proc.
// But be aware that the handle will be destroyed on destructor!
//
class Pj_External_Thread : public Pj_Thread
{
public:
    Pj_External_Thread()
    {
    }

    //
    // Register external thread so that pjlib functions can work
    // in that thread.
    //
    pj_status_t register_this_thread( const char *name=NULL )
    {
        return Pj_Thread_API::register_this_thread(desc_, &thread_,name);
    }

private:
    pj_thread_desc desc_;
};


//
// Thread specific data/thread local storage/TLS.
//
class Pj_Thread_Local_API
{
public:
    //
    // Allocate thread local storage (TLS) index.
    //
    static pj_status_t alloc(long *index)
    {
        return pj_thread_local_alloc(index);
    }

    //
    // Free TLS index.
    //
    static void free(long index)
    {
        pj_thread_local_free(index);
    }

    //
    // Set thread specific data.
    //
    static pj_status_t set(long index, void *value)
    {
        return pj_thread_local_set(index, value);
    }

    //
    // Get thread specific data.
    //
    static void *get(long index)
    {
        return pj_thread_local_get(index);
    }

};

//
// Atomic variable
//
// How to use:
//   Pj_Atomic_Var var(pool, 0);
//   var.set(..);
//
class Pj_Atomic_Var : public Pj_Object
{
public:
    //
    // Default constructor, initialize variable with NULL.
    //
    Pj_Atomic_Var()
        : var_(NULL)
    {
    }

    //
    // Construct atomic variable.
    //
    Pj_Atomic_Var(Pj_Pool *pool, pj_atomic_value_t value)
        : var_(NULL)
    {
        create(pool, value);
    }

    //
    // Destructor.
    //
    ~Pj_Atomic_Var()
    {
        destroy();
    }

    //
    // Create atomic variable.
    //
    pj_status_t create( Pj_Pool *pool, pj_atomic_value_t value)
    {
        destroy();
	return pj_atomic_create(pool->pool_(), value, &var_);
    }

    //
    // Destroy.
    //
    void destroy()
    {
        if (var_) {
            pj_atomic_destroy(var_);
            var_ = NULL;
        }
    }

    //
    // Get pjlib compatible atomic variable.
    //
    pj_atomic_t *pj_atomic_t_()
    {
	return var_;
    }

    //
    // Set the value.
    //
    void set(pj_atomic_value_t val)
    {
	pj_atomic_set(var_, val);
    }

    //
    // Get the value.
    //
    pj_atomic_value_t get()
    {
	return pj_atomic_get(var_);
    }

    //
    // Increment.
    //
    void inc()
    {
	pj_atomic_inc(var_);
    }

    //
    // Increment and get the result.
    //
    pj_atomic_value_t inc_and_get()
    {
        return pj_atomic_inc_and_get(var_);
    }

    //
    // Decrement.
    //
    void dec()
    {
	pj_atomic_dec(var_);
    }

    //
    // Decrement and get the result.
    //
    pj_atomic_value_t dec_and_get()
    {
        return pj_atomic_dec_and_get(var_);
    }

    //
    // Add the variable.
    //
    void add(pj_atomic_value_t value)
    {
        pj_atomic_add(var_, value);
    }

    //
    // Add the variable and get the value.
    //
    pj_atomic_value_t add_and_get(pj_atomic_value_t value)
    {
        return pj_atomic_add_and_get(var_, value );
    }

private:
    pj_atomic_t *var_;
};


//
// Mutex
//
class Pj_Mutex : public Pj_Object
{
public:
    //
    // Mutex type.
    //
    enum Type
    {
	DEFAULT = PJ_MUTEX_DEFAULT,
	SIMPLE = PJ_MUTEX_SIMPLE,
	RECURSE = PJ_MUTEX_RECURSE,
    };

    //
    // Default constructor will create default mutex.
    //
    explicit Pj_Mutex(Pj_Pool *pool, Type type = DEFAULT,
                      const char *name = NULL)
        : mutex_(NULL)
    {
        create(pool, type, name);
    }

    //
    // Destructor.
    //
    ~Pj_Mutex()
    {
        destroy();
    }

    //
    // Create mutex.
    //
    pj_status_t create( Pj_Pool *pool, Type type, const char *name = NULL)
    {
        destroy();
	return pj_mutex_create( pool->pool_(), name, type,
                                &mutex_ );
    }

    //
    // Create simple mutex.
    //
    pj_status_t create_simple( Pj_Pool *pool,const char *name = NULL)
    {
        return create(pool, SIMPLE, name);
    }

    //
    // Create recursive mutex.
    //
    pj_status_t create_recursive( Pj_Pool *pool, const char *name = NULL )
    {
        return create(pool, RECURSE, name);
    }

    //
    // Get pjlib compatible mutex object.
    //
    pj_mutex_t *pj_mutex_t_()
    {
	return mutex_;
    }

    //
    // Destroy mutex.
    //
    void destroy()
    {
        if (mutex_) {
	    pj_mutex_destroy(mutex_);
            mutex_ = NULL;
        }
    }

    //
    // Lock mutex.
    //
    pj_status_t acquire()
    {
	return pj_mutex_lock(mutex_);
    }

    //
    // Unlock mutex.
    //
    pj_status_t release()
    {
	return pj_mutex_unlock(mutex_);
    }

    //
    // Try locking the mutex.
    //
    pj_status_t tryacquire()
    {
	return pj_mutex_trylock(mutex_);
    }

private:
    pj_mutex_t *mutex_;
};


//
// Semaphore
//
class Pj_Semaphore : public Pj_Object
{
public:
    //
    // Construct semaphore
    //
    Pj_Semaphore(Pj_Pool *pool, unsigned max,
                 unsigned initial = 0, const char *name = NULL)
    : sem_(NULL)
    {
	create(pool, max, initial, name);
    }

    //
    // Destructor.
    //
    ~Pj_Semaphore()
    {
        destroy();
    }

    //
    // Create semaphore
    //
    pj_status_t create( Pj_Pool *pool, unsigned max,
                        unsigned initial = 0, const char *name = NULL )
    {
        destroy();
	return pj_sem_create( pool->pool_(), name, initial, max, &sem_);
    }

    //
    // Destroy semaphore.
    //
    void destroy()
    {
        if (sem_) {
            pj_sem_destroy(sem_);
            sem_ = NULL;
        }
    }

    //
    // Get pjlib compatible semaphore object.
    //
    pj_sem_t *pj_sem_t_()
    {
	return (pj_sem_t*)this;
    }

    //
    // Wait semaphore.
    //
    pj_status_t wait()
    {
	return pj_sem_wait(this->pj_sem_t_());
    }

    //
    // Wait semaphore.
    //
    pj_status_t acquire()
    {
	return wait();
    }

    //
    // Try wait semaphore.
    //
    pj_status_t trywait()
    {
	return pj_sem_trywait(this->pj_sem_t_());
    }

    //
    // Try wait semaphore.
    //
    pj_status_t tryacquire()
    {
	return trywait();
    }

    //
    // Post semaphore.
    //
    pj_status_t post()
    {
	return pj_sem_post(this->pj_sem_t_());
    }

    //
    // Post semaphore.
    //
    pj_status_t release()
    {
	return post();
    }

private:
    pj_sem_t *sem_;
};


//
// Event object.
//
class Pj_Event
{
public:
    //
    // Construct event object.
    //
    Pj_Event( Pj_Pool *pool, bool manual_reset = false,
              bool initial = false, const char *name = NULL )
    : event_(NULL)
    {
        create(pool, manual_reset, initial, name);
    }

    //
    // Destructor.
    //
    ~Pj_Event()
    {
        destroy();
    }

    //
    // Create event object.
    //
    pj_status_t create( Pj_Pool *pool, bool manual_reset = false, 
                        bool initial = false, const char *name = NULL)
    {
        destroy();
	return pj_event_create(pool->pool_(), name, manual_reset, initial,
                               &event_);
    }

    //
    // Get pjlib compatible event object.
    //
    pj_event_t *pj_event_t_()
    {
	return event_;
    }

    //
    // Destroy event object.
    //
    void destroy()
    {
        if (event_) {
	    pj_event_destroy(event_);
            event_ = NULL;
        }
    }

    //
    // Wait.
    //
    pj_status_t wait()
    {
	return pj_event_wait(event_);
    }

    //
    // Try wait.
    //
    pj_status_t trywait()
    {
	return pj_event_trywait(event_);
    }

    //
    // Set event state to signalled.
    //
    pj_status_t set()
    {
	return pj_event_set(this->pj_event_t_());
    }

    //
    // Release one waiting thread.
    //
    pj_status_t pulse()
    {
	return pj_event_pulse(this->pj_event_t_());
    }

    //
    // Set a non-signalled.
    //
    pj_status_t reset()
    {
	return pj_event_reset(this->pj_event_t_());
    }

private:
    pj_event_t *event_;
};

//
// Timestamp
//
class Pj_Timestamp
{
public:
    pj_status_t get_timestamp()
    {
	return pj_get_timestamp(&ts_);
    }

    Pj_Timestamp& operator += (const Pj_Timestamp &rhs)
    {
	pj_add_timestamp(&ts_, &rhs.ts_);
	return *this;
    }

    Pj_Timestamp& operator -= (const Pj_Timestamp &rhs)
    {
	pj_sub_timestamp(&ts_, &rhs.ts_);
	return *this;
    }

    Pj_Time_Val to_time() const
    {
	Pj_Timestamp zero;
	pj_memset(&zero, 0, sizeof(zero));
	return Pj_Time_Val(pj_elapsed_time(&zero.ts_, &ts_));
    }

    pj_uint32_t to_msec() const
    {
	Pj_Timestamp zero;
	pj_memset(&zero, 0, sizeof(zero));
	return pj_elapsed_msec(&zero.ts_, &ts_);
    }

    pj_uint32_t to_usec() const
    {
	Pj_Timestamp zero;
	pj_memset(&zero, 0, sizeof(zero));
	return pj_elapsed_usec(&zero.ts_, &ts_);
    }

    pj_uint32_t to_nanosec() const
    {
	Pj_Timestamp zero;
	pj_memset(&zero, 0, sizeof(zero));
	return pj_elapsed_nanosec(&zero.ts_, &ts_);
    }

    pj_uint32_t to_cycle() const
    {
	Pj_Timestamp zero;
	pj_memset(&zero, 0, sizeof(zero));
	return pj_elapsed_cycle(&zero.ts_, &ts_);
    }

private:
    pj_timestamp    ts_;
};


//
// OS abstraction.
//
class Pj_OS_API
{
public:
    //
    // Get current time.
    //
    static pj_status_t gettimeofday( Pj_Time_Val *tv )
    {
	return pj_gettimeofday(tv);
    }

    //
    // Parse to time of day.
    //
    static pj_status_t time_decode( const Pj_Time_Val *tv, 
                                    pj_parsed_time *pt )
    {
	return pj_time_decode(tv, pt);
    }

    //
    // Parse from time of day.
    //
    static pj_status_t time_encode( const pj_parsed_time *pt, 
                                    Pj_Time_Val *tv)
    {
	return pj_time_encode(pt, tv);
    }

    //
    // Convert to GMT.
    //
    static pj_status_t time_local_to_gmt( Pj_Time_Val *tv )
    {
	return pj_time_local_to_gmt( tv );
    }

    //
    // Convert time to local.
    //
    static pj_status_t time_gmt_to_local( Pj_Time_Val *tv) 
    {
	return pj_time_gmt_to_local( tv );
    }
};

//
// Timeval inlines.
//
inline pj_status_t Pj_Time_Val::gettimeofday()
{
    return Pj_OS_API::gettimeofday(this);
}

inline pj_parsed_time Pj_Time_Val::decode()
{
    pj_parsed_time pt;
    Pj_OS_API::time_decode(this, &pt);
    return pt;
}

inline pj_status_t Pj_Time_Val::encode(const pj_parsed_time *pt)
{
    return Pj_OS_API::time_encode(pt, this);
}

inline pj_status_t Pj_Time_Val::to_gmt()
{
    return Pj_OS_API::time_local_to_gmt(this);
}

inline pj_status_t Pj_Time_Val::to_local()
{
    return Pj_OS_API::time_gmt_to_local(this);
}

#endif	/* __PJPP_OS_HPP__ */

