/*
 * Helper functions for the Wine tools
 *
 * Copyright 2021 Alexandre Julliard
 *
 * 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
 */

#ifndef __WINE_TOOLS_H
#define __WINE_TOOLS_H

#ifndef __WINE_CONFIG_H
# error You must include config.h to use this header
#endif

#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>
#ifdef HAVE_SYS_SYSCTL_H
# include <sys/sysctl.h>
#endif

#ifdef _WIN32
# include <direct.h>
# include <io.h>
# include <process.h>
# define mkdir(path,mode) mkdir(path)
# ifndef S_ISREG
#  define S_ISREG(mod) (((mod) & _S_IFMT) == _S_IFREG)
# endif
# ifdef _MSC_VER
#  define popen _popen
#  define pclose _pclose
#  define strtoll _strtoi64
#  define strtoull _strtoui64
#  define strncasecmp _strnicmp
#  define strcasecmp _stricmp
# endif
#else
extern char **environ;
# include <spawn.h>
# include <sys/wait.h>
# include <unistd.h>
# ifndef O_BINARY
#  define O_BINARY 0
# endif
# ifndef __int64
#   if defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__)
#     define __int64 long
#   else
#     define __int64 long long
#   endif
# endif
#endif

#if !defined(__GNUC__) && !defined(__attribute__)
#define __attribute__(x)
#endif

#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif

#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#endif

struct target
{
    enum { CPU_i386, CPU_x86_64, CPU_ARM, CPU_ARM64 } cpu;

    enum
    {
        PLATFORM_UNSPECIFIED,
        PLATFORM_APPLE,
        PLATFORM_ANDROID,
        PLATFORM_LINUX,
        PLATFORM_FREEBSD,
        PLATFORM_SOLARIS,
        PLATFORM_WINDOWS,
        PLATFORM_MINGW,
        PLATFORM_CYGWIN
    } platform;
};

static inline void *xmalloc( size_t size )
{
    void *res = malloc( size ? size : 1 );

    if (res == NULL)
    {
        fprintf( stderr, "Virtual memory exhausted.\n" );
        exit(1);
    }
    return res;
}

static inline void *xrealloc (void *ptr, size_t size)
{
    void *res = realloc( ptr, size );

    if (size && res == NULL)
    {
        fprintf( stderr, "Virtual memory exhausted.\n" );
        exit(1);
    }
    return res;
}

static inline char *xstrdup( const char *str )
{
    return strcpy( xmalloc( strlen(str)+1 ), str );
}

static inline int strendswith( const char *str, const char *end )
{
    int l = strlen( str );
    int m = strlen( end );
    return l >= m && !strcmp( str + l - m, end );
}

static char *strmake( const char* fmt, ... ) __attribute__ ((__format__ (__printf__, 1, 2)));
static inline char *strmake( const char* fmt, ... )
{
    int n;
    size_t size = 100;
    va_list ap;

    for (;;)
    {
        char *p = xmalloc( size );
        va_start( ap, fmt );
	n = vsnprintf( p, size, fmt, ap );
	va_end( ap );
        if (n == -1) size *= 2;
        else if ((size_t)n >= size) size = n + 1;
        else return p;
        free( p );
    }
}

/* string array functions */

struct strarray
{
    unsigned int count;  /* strings in use */
    unsigned int size;   /* total allocated size */
    const char **str;
};

static const struct strarray empty_strarray;

static inline void strarray_add( struct strarray *array, const char *str )
{
    if (array->count == array->size)
    {
	if (array->size) array->size *= 2;
        else array->size = 16;
	array->str = xrealloc( array->str, sizeof(array->str[0]) * array->size );
    }
    array->str[array->count++] = str;
}

static inline void strarray_addall( struct strarray *array, struct strarray added )
{
    unsigned int i;

    for (i = 0; i < added.count; i++) strarray_add( array, added.str[i] );
}

static inline int strarray_exists( const struct strarray *array, const char *str )
{
    unsigned int i;

    for (i = 0; i < array->count; i++) if (!strcmp( array->str[i], str )) return 1;
    return 0;
}

static inline void strarray_add_uniq( struct strarray *array, const char *str )
{
    if (!strarray_exists( array, str )) strarray_add( array, str );
}

static inline void strarray_addall_uniq( struct strarray *array, struct strarray added )
{
    unsigned int i;

    for (i = 0; i < added.count; i++) strarray_add_uniq( array, added.str[i] );
}

static inline struct strarray strarray_fromstring( const char *str, const char *delim )
{
    struct strarray array = empty_strarray;
    char *buf = xstrdup( str );
    const char *tok;

    for (tok = strtok( buf, delim ); tok; tok = strtok( NULL, delim ))
        strarray_add( &array, xstrdup( tok ));
    free( buf );
    return array;
}

static inline struct strarray strarray_frompath( const char *path )
{
    if (!path) return empty_strarray;
#ifdef _WIN32
    return strarray_fromstring( path, ";" );
#else
    return strarray_fromstring( path, ":" );
#endif
}

static inline char *strarray_tostring( struct strarray array, const char *sep )
{
    char *str;
    unsigned int i, len = 1 + (array.count - 1) * strlen(sep);

    if (!array.count) return xstrdup("");
    for (i = 0; i < array.count; i++) len += strlen( array.str[i] );
    str = xmalloc( len );
    strcpy( str, array.str[0] );
    for (i = 1; i < array.count; i++)
    {
        strcat( str, sep );
        strcat( str, array.str[i] );
    }
    return str;
}

static inline void strarray_qsort( struct strarray *array, int (*func)(const char **, const char **) )
{
    if (array->count) qsort( array->str, array->count, sizeof(*array->str), (void *)func );
}

static inline const char *strarray_bsearch( const struct strarray *array, const char *str,
                                            int (*func)(const char **, const char **) )
{
    char **res = NULL;

    if (array->count) res = bsearch( &str, array->str, array->count, sizeof(*array->str), (void *)func );
    return res ? *res : NULL;
}

static inline void strarray_trace( struct strarray args )
{
    unsigned int i;

    for (i = 0; i < args.count; i++)
    {
        if (strpbrk( args.str[i], " \t\n\r")) printf( "\"%s\"", args.str[i] );
        else printf( "%s", args.str[i] );
        putchar( i < args.count - 1 ? ' ' : '\n' );
    }
}

static inline int strarray_spawn( struct strarray args )
{
#ifdef _WIN32
    strarray_add( &args, NULL );
    return _spawnvp( _P_WAIT, args.str[0], args.str );
#else
    pid_t pid, wret;
    int status;

    strarray_add( &args, NULL );
    if (posix_spawnp( &pid, args.str[0], NULL, NULL, (char **)args.str, environ ))
        return -1;

    while (pid != (wret = waitpid( pid, &status, 0 )))
        if (wret == -1 && errno != EINTR) break;

    if (pid == wret && WIFEXITED(status)) return WEXITSTATUS(status);
    return 255; /* abnormal exit with an abort or an interrupt */
#endif
}

static inline char *get_basename( const char *file )
{
    const char *ret = strrchr( file, '/' );
    return xstrdup( ret ? ret + 1 : file );
}

static inline char *get_basename_noext( const char *file )
{
    char *ext, *ret = get_basename( file );
    if ((ext = strrchr( ret, '.' ))) *ext = 0;
    return ret;
}

static inline char *get_dirname( const char *file )
{
    const char *end = strrchr( file, '/' );
    if (!end) return xstrdup( "." );
    if (end == file) end++;
    return strmake( "%.*s", (int)(end - file), file );
}

static inline char *replace_extension( const char *name, const char *old_ext, const char *new_ext )
{
    int name_len = strlen( name );

    if (strendswith( name, old_ext )) name_len -= strlen( old_ext );
    return strmake( "%.*s%s", name_len, name, new_ext );
}

/* temp files management */

extern const char *temp_dir;
extern struct strarray temp_files;

static inline char *make_temp_dir(void)
{
    unsigned int value = time(NULL) + getpid();
    int count;
    char *name;
    const char *tmpdir = NULL;

    for (count = 0; count < 0x8000; count++)
    {
        if (tmpdir)
            name = strmake( "%s/tmp%08x", tmpdir, value );
        else
            name = strmake( "tmp%08x", value );
        if (!mkdir( name, 0700 )) return name;
        value += 7777;
        if (errno == EACCES && !tmpdir)
        {
            if (!(tmpdir = getenv("TMPDIR"))) tmpdir = "/tmp";
        }
        free( name );
    }
    fprintf( stderr, "failed to create directory for temp files\n" );
    exit(1);
}

static inline char *make_temp_file( const char *prefix, const char *suffix )
{
    static unsigned int value;
    int fd, count;
    char *name;

    if (!temp_dir) temp_dir = make_temp_dir();
    if (!suffix) suffix = "";
    if (!prefix) prefix = "tmp";
    else prefix = get_basename_noext( prefix );

    for (count = 0; count < 0x8000; count++)
    {
        name = strmake( "%s/%s-%08x%s", temp_dir, prefix, value++, suffix );
        fd = open( name, O_RDWR | O_CREAT | O_EXCL, 0600 );
        if (fd >= 0)
        {
#ifdef HAVE_SIGPROCMASK /* block signals while manipulating the temp files list */
            sigset_t mask_set, old_set;

            sigemptyset( &mask_set );
            sigaddset( &mask_set, SIGHUP );
            sigaddset( &mask_set, SIGTERM );
            sigaddset( &mask_set, SIGINT );
            sigprocmask( SIG_BLOCK, &mask_set, &old_set );
            strarray_add( &temp_files, name );
            sigprocmask( SIG_SETMASK, &old_set, NULL );
#else
            strarray_add( &temp_files, name );
#endif
            close( fd );
            return name;
        }
        free( name );
    }
    fprintf( stderr, "failed to create temp file for %s%s in %s\n", prefix, suffix, temp_dir );
    exit(1);
}

static inline void remove_temp_files(void)
{
    unsigned int i;

    for (i = 0; i < temp_files.count; i++) if (temp_files.str[i]) unlink( temp_files.str[i] );
    if (temp_dir) rmdir( temp_dir );
}


static inline void init_signals( void (*cleanup)(int) )
{
    signal( SIGTERM, cleanup );
    signal( SIGINT, cleanup );
#ifdef SIGHUP
    signal( SIGHUP, cleanup );
#endif
}


static inline void *read_file( const char *name, size_t *size )
{
    struct stat st;
    int res, fd;
    void *data;

    if ((fd = open( name, O_RDONLY | O_BINARY )) == -1) return NULL;
    fstat( fd, &st );
    data = xmalloc( st.st_size );
    res = read( fd, data, st.st_size );
    if (res == -1)
    {
        free( data );
        data = NULL;
        *size = 0;
    }
    else *size = res;
    close( fd );
    return data;
}


static inline struct target get_default_target(void)
{
    struct target target;
#ifdef __i386__
    target.cpu = CPU_i386;
#elif defined(__x86_64__)
    target.cpu = CPU_x86_64;
#elif defined(__arm__)
    target.cpu = CPU_ARM;
#elif defined(__aarch64__)
    target.cpu = CPU_ARM64;
#else
#error Unsupported CPU
#endif

#ifdef __APPLE__
    target.platform = PLATFORM_APPLE;
#elif defined(__ANDROID__)
    target.platform = PLATFORM_ANDROID;
#elif defined(__linux__)
    target.platform = PLATFORM_LINUX;
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
    target.platform = PLATFORM_FREEBSD;
#elif defined(__sun)
    target.platform = PLATFORM_SOLARIS;
#elif defined(__CYGWIN__)
    target.platform = PLATFORM_CYGWIN;
#elif defined(_WIN32)
    target.platform = PLATFORM_MINGW;
#else
    target.platform = PLATFORM_UNSPECIFIED;
#endif

    return target;
}


static inline unsigned int get_target_ptr_size( struct target target )
{
    static const unsigned int sizes[] =
    {
        [CPU_i386]      = 4,
        [CPU_x86_64]    = 8,
        [CPU_ARM]       = 4,
        [CPU_ARM64]     = 8,
    };
    return sizes[target.cpu];
}


static inline void set_target_ptr_size( struct target *target, unsigned int size )
{
    switch (target->cpu)
    {
    case CPU_i386:
        if (size == 8) target->cpu = CPU_x86_64;
        break;
    case CPU_x86_64:
        if (size == 4) target->cpu = CPU_i386;
        break;
    case CPU_ARM:
        if (size == 8) target->cpu = CPU_ARM64;
        break;
    case CPU_ARM64:
        if (size == 4) target->cpu = CPU_ARM;
        break;
    }
}


static inline int get_cpu_from_name( const char *name )
{
    static const struct
    {
        const char *name;
        int         cpu;
    } cpu_names[] =
    {
        { "i386",      CPU_i386 },
        { "i486",      CPU_i386 },
        { "i586",      CPU_i386 },
        { "i686",      CPU_i386 },
        { "i786",      CPU_i386 },
        { "x86_64",    CPU_x86_64 },
        { "amd64",     CPU_x86_64 },
        { "aarch64",   CPU_ARM64 },
        { "arm64",     CPU_ARM64 },
        { "arm",       CPU_ARM },
    };
    unsigned int i;

    for (i = 0; i < ARRAY_SIZE(cpu_names); i++)
        if (!strncmp( cpu_names[i].name, name, strlen(cpu_names[i].name) )) return cpu_names[i].cpu;
    return -1;
}


static inline int get_platform_from_name( const char *name )
{
    static const struct
    {
        const char *name;
        int         platform;
    } platform_names[] =
    {
        { "macos",       PLATFORM_APPLE },
        { "darwin",      PLATFORM_APPLE },
        { "android",     PLATFORM_ANDROID },
        { "linux",       PLATFORM_LINUX },
        { "freebsd",     PLATFORM_FREEBSD },
        { "solaris",     PLATFORM_SOLARIS },
        { "mingw32",     PLATFORM_MINGW },
        { "windows-gnu", PLATFORM_MINGW },
        { "winnt",       PLATFORM_MINGW },
        { "windows",     PLATFORM_WINDOWS },
        { "cygwin",      PLATFORM_CYGWIN },
    };
    unsigned int i;

    for (i = 0; i < ARRAY_SIZE(platform_names); i++)
        if (!strncmp( platform_names[i].name, name, strlen(platform_names[i].name) ))
            return platform_names[i].platform;
    return -1;
};


static inline const char *get_arch_dir( struct target target )
{
    static const char *cpu_names[] =
    {
        [CPU_i386]   = "i386",
        [CPU_x86_64] = "x86_64",
        [CPU_ARM]    = "arm",
        [CPU_ARM64]  = "aarch64"
    };

    if (!cpu_names[target.cpu]) return "";

    switch (target.platform)
    {
    case PLATFORM_WINDOWS:
    case PLATFORM_CYGWIN:
    case PLATFORM_MINGW:
        return strmake( "/%s-windows", cpu_names[target.cpu] );
    default:
        return strmake( "/%s-unix", cpu_names[target.cpu] );
    }
}

static inline int parse_target( const char *name, struct target *target )
{
    int res;
    char *p, *spec = xstrdup( name );

    /* target specification is in the form CPU-MANUFACTURER-OS or CPU-MANUFACTURER-KERNEL-OS */

    /* get the CPU part */

    if ((p = strchr( spec, '-' )))
    {
        *p++ = 0;
        if ((res = get_cpu_from_name( spec )) == -1)
        {
            free( spec );
            return 0;
        }
        target->cpu = res;
    }
    else if (!strcmp( spec, "mingw32" ))
    {
        target->cpu = CPU_i386;
        p = spec;
    }
    else
    {
        free( spec );
        return 0;
    }

    /* get the OS part */

    target->platform = PLATFORM_UNSPECIFIED;  /* default value */
    for (;;)
    {
        if ((res = get_platform_from_name( p )) != -1)
        {
            target->platform = res;
            break;
        }
        if (!(p = strchr( p, '-' ))) break;
        p++;
    }

    free( spec );
    return 1;
}


static inline struct target init_argv0_target( const char *argv0 )
{
    char *name = get_basename( argv0 );
    struct target target;

    if (!strchr( name, '-' ) || !parse_target( name, &target ))
        target = get_default_target();

    free( name );
    return target;
}


static inline char *get_argv0_dir( const char *argv0 )
{
#ifndef _WIN32
    char *dir = NULL;

#if defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)
    dir = realpath( "/proc/self/exe", NULL );
#elif defined (__FreeBSD__) || defined(__DragonFly__)
    static int pathname[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
    size_t path_size = PATH_MAX;
    char *path = xmalloc( path_size );
    if (!sysctl( pathname, ARRAY_SIZE(pathname), path, &path_size, NULL, 0 ))
        dir = realpath( path, NULL );
    free( path );
#endif
    if (!dir && !(dir = realpath( argv0, NULL ))) return NULL;
    return get_dirname( dir );
#else
    return get_dirname( argv0 );
#endif
}


/* output buffer management */

extern unsigned char *output_buffer;
extern size_t output_buffer_pos;
extern size_t output_buffer_size;

static inline void check_output_buffer_space( size_t size )
{
    if (output_buffer_pos + size >= output_buffer_size)
    {
        output_buffer_size = max( output_buffer_size * 2, output_buffer_pos + size );
        output_buffer = xrealloc( output_buffer, output_buffer_size );
    }
}

static inline void init_output_buffer(void)
{
    output_buffer_size = 1024;
    output_buffer_pos = 0;
    output_buffer = xmalloc( output_buffer_size );
}

static inline void put_data( const void *data, size_t size )
{
    check_output_buffer_space( size );
    memcpy( output_buffer + output_buffer_pos, data, size );
    output_buffer_pos += size;
}

static inline void put_byte( unsigned char val )
{
    check_output_buffer_space( 1 );
    output_buffer[output_buffer_pos++] = val;
}

static inline void put_word( unsigned short val )
{
    check_output_buffer_space( 2 );
    output_buffer[output_buffer_pos++] = val;
    output_buffer[output_buffer_pos++] = val >> 8;
}

static inline void put_dword( unsigned int val )
{
    check_output_buffer_space( 4 );
    output_buffer[output_buffer_pos++] = val;
    output_buffer[output_buffer_pos++] = val >> 8;
    output_buffer[output_buffer_pos++] = val >> 16;
    output_buffer[output_buffer_pos++] = val >> 24;
}

static inline void put_qword( unsigned int val )
{
    put_dword( val );
    put_dword( 0 );
}

static inline void align_output( unsigned int align )
{
    size_t size = align - (output_buffer_pos % align);

    if (size == align) return;
    check_output_buffer_space( size );
    memset( output_buffer + output_buffer_pos, 0, size );
    output_buffer_pos += size;
}

static inline void flush_output_buffer( const char *name )
{
    int fd = open( name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666 );

    if (fd == -1 || write( fd, output_buffer, output_buffer_pos ) != output_buffer_pos)
    {
        perror( name );
        exit(1);
    }
    close( fd );
    free( output_buffer );
}

/* command-line option parsing */
/* partly based on the Glibc getopt() implementation */

struct long_option
{
    const char *name;
    int has_arg;
    int val;
};

static inline struct strarray parse_options( int argc, char **argv, const char *short_opts,
                                             const struct long_option *long_opts, int long_only,
                                             void (*callback)( int, char* ) )
{
    struct strarray ret = empty_strarray;
    const char *flag;
    char *start, *end;
    int i;

#define OPT_ERR(fmt) { callback( '?', strmake( fmt, argv[1] )); continue; }

    for (i = 1; i < argc; i++)
    {
        if (argv[i][0] != '-' || !argv[i][1])  /* not an option */
        {
            strarray_add( &ret, argv[i] );
            continue;
        }
        if (!strcmp( argv[i], "--" ))
        {
            /* add remaining args */
            while (++i < argc) strarray_add( &ret, argv[i] );
            break;
        }
        start = argv[i] + 1 + (argv[i][1] == '-');

        if (argv[i][1] == '-' || (long_only && (argv[i][2] || !strchr( short_opts, argv[i][1] ))))
        {
            /* handle long option */
            const struct long_option *opt, *found = NULL;
            int count = 0;

            if (!(end = strchr( start, '=' ))) end = start + strlen(start);
            for (opt = long_opts; opt && opt->name; opt++)
            {
                if (strncmp( opt->name, start, end - start )) continue;
                if (!opt->name[end - start])  /* exact match */
                {
                    found = opt;
                    count = 1;
                    break;
                }
                if (!found)
                {
                    found = opt;
                    count++;
                }
                else if (long_only || found->has_arg != opt->has_arg || found->val != opt->val)
                {
                    count++;
                }
            }

            if (count > 1) OPT_ERR( "option '%s' is ambiguous" );

            if (found)
            {
                if (*end)
                {
                    if (!found->has_arg) OPT_ERR( "argument not allowed in '%s'" );
                    end++;  /* skip '=' */
                }
                else if (found->has_arg == 1)
                {
                    if (i == argc - 1) OPT_ERR( "option '%s' requires an argument" );
                    end = argv[++i];
                }
                else end = NULL;

                callback( found->val, end );
                continue;
            }
            if (argv[i][1] == '-' || !long_only || !strchr( short_opts, argv[i][1] ))
                OPT_ERR( "unrecognized option '%s'" );
        }

        /* handle short option */
        for ( ; *start; start++)
        {
            if (!(flag = strchr( short_opts, *start ))) OPT_ERR( "invalid option '%s'" );
            if (flag[1] == ':')
            {
                end = start + 1;
                if (!*end) end = NULL;
                if (flag[2] != ':' && !end)
                {
                    if (i == argc - 1) OPT_ERR( "option '%s' requires an argument" );
                    end = argv[++i];
                }
                callback( *start, end );
                break;
            }
            callback( *start, NULL );
        }
    }
    return ret;
#undef OPT_ERR
}

#endif /* __WINE_TOOLS_H */
