/* $Id$ */
/* 
 * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
 * Copyright (C) 2003-2008 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__ */

