/* util.h
 * This file belongs to Worker, a file manager for UN*X/X11.
 * Copyright (C) 2001-2021 Ralf Hoffmann.
 * You can contact me at: ralf@boomerangsworld.de
 *   or http://www.boomerangsworld.de/worker
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifndef UTIL_H
#define UTIL_H

#include "aguixdefs.h"
#include <string>
#include <sstream>
#include <stdexcept>
#include <vector>
#include <cinttypes>

int createLines( const char*, char ***, const char split = '|' );

namespace AGUIXUtils
{
    std::string bytes_to_human_readable( loff_t number,
                                         int threshold = 1);

    std::string tolower( const std::string &str );
    
    bool stringIsShorter( const char *str, int len );

    std::string formatStringToString( const char *format, ... ) __attribute__ ((format (printf, 1, 2)));

    loff_t convertHumanStringToNumber( const std::string &str );

    typedef enum {
        BM_TRADITIONAL,
        BM_SI,
        BM_IEC,
        BM_SYSTEM_SETTING
    } byte_multiplier_t;

    std::string bytes_to_human_readable_f( loff_t number,
                                           int threshold = 1,
                                           int precision = 1,
                                           byte_multiplier_t suffix_format = BM_IEC,
                                           loff_t precision_hint = 0 );
    std::string bytes_to_human_readable_f( double number,
                                           int threshold = 1,
                                           int precision = 1,
                                           byte_multiplier_t suffix_format = BM_IEC,
                                           double precision_hint = 0.0 );

    template< class T > std::string convertToString( const T &v )
    {
        std::ostringstream osstr1;

        osstr1 << v;
	
        return osstr1.str();
    }

    template< class T > T convertFromString( const std::string &s,
                                             std::ios_base &(*stream_manip_func)( std::ios_base & ) = std::dec )
    {
        std::istringstream isstr1( s );

        T v;

        isstr1 >> stream_manip_func;
        isstr1 >> v;

        if ( isstr1.fail() ) throw std::runtime_error( "convertFromString failed" );

        return v;
    }

    template< class T > bool convertFromString( const std::string &s, T &v )
    {
        try {
            v = convertFromString<T>( s );
        } catch ( const std::runtime_error &e ) {
            return false;
        }
        return true;
    }

    int calc_precision( double v );

    void split_string( std::vector< std::string > &v,
                       const std::string &str1,
                       const char split_element );

    bool starts_with( const std::string &str,
                      const std::string &prefix );

    bool ends_with( const std::string &str,
                    const std::string &suffix );
    bool contains( const std::string &str,
                   const std::string &infix );

    bool char_in_string( const char ch,
                         const std::string &str );

    void rstrip( std::string &str );
    void rstrip( std::string &str, const std::string &strip_chars );
    void strip( std::string &str );

    /* removes the character from the string. is utf8 safe */
    std::string remove_char( const std::string &str,
                             char ch );

    std::string timeToString( time_t t );
    bool parseStringToTime( const std::string &time_string,
                            time_t *return_time );

    std::string escape_uri( const std::string &uri );
    std::string unescape_uri( const std::string &uri );

    typedef enum {
                  ESCAPE_JSON
    } escape_type_t;
    
    int escape_characters( const std::string &input,
                           std::string &output,
                           escape_type_t type );
    int unescape_characters( const std::string &input,
                             std::string &output,
                             escape_type_t type );

    // this function replaces the first occurance of %s with a
    // correctly quoted string. This function does not take into
    // accounted protected characters like \%s.
    std::string replace_percent_s_quoted( const std::string &src,
                                          const std::string &replacement,
                                          std::string *return_suffix );

    uint64_t current_time_ms();
}

#define TIMEMEASURE_T struct timeval
#define TIMEMEASURE_START(x) gettimeofday( &(x), NULL )
#define TIMEMEASURE_END(x) TIMEMEASURE_START(x)
#define TIMEMEASURE_PRINT_DIFF(t_new,t_old,info) {          \
    long long us = (t_new).tv_sec - (t_old).tv_sec; \
    us *= 1000000;                                  \
    us += (t_new).tv_usec - (t_old).tv_usec;        \
    printf( "%s: %lld ms\n", (info), us / 1000 );   \
    }

#endif

/* Local Variables: */
/* mode:c++ */
/* End: */
