/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkString_DEFINED
#define SkString_DEFINED

#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkTypes.h"
#include "include/private/SkMalloc.h"
#include "include/private/SkTArray.h"
#include "include/private/SkTo.h"

#include <stdarg.h>
#include <string.h>
#include <atomic>
#include <string>

/*  Some helper functions for C strings */
static inline bool SkStrStartsWith(const char string[], const char prefixStr[]) {
    SkASSERT(string);
    SkASSERT(prefixStr);
    return !strncmp(string, prefixStr, strlen(prefixStr));
}
static inline bool SkStrStartsWith(const char string[], const char prefixChar) {
    SkASSERT(string);
    return (prefixChar == *string);
}

bool SkStrEndsWith(const char string[], const char suffixStr[]);
bool SkStrEndsWith(const char string[], const char suffixChar);

int SkStrStartsWithOneOf(const char string[], const char prefixes[]);

static inline int SkStrFind(const char string[], const char substring[]) {
    const char *first = strstr(string, substring);
    if (nullptr == first) return -1;
    return SkToInt(first - &string[0]);
}

static inline int SkStrFindLastOf(const char string[], const char subchar) {
    const char* last = strrchr(string, subchar);
    if (nullptr == last) return -1;
    return SkToInt(last - &string[0]);
}

static inline bool SkStrContains(const char string[], const char substring[]) {
    SkASSERT(string);
    SkASSERT(substring);
    return (-1 != SkStrFind(string, substring));
}
static inline bool SkStrContains(const char string[], const char subchar) {
    SkASSERT(string);
    char tmp[2];
    tmp[0] = subchar;
    tmp[1] = '\0';
    return (-1 != SkStrFind(string, tmp));
}

static inline char *SkStrDup(const char string[]) {
    char *ret = (char *) sk_malloc_throw(strlen(string)+1);
    memcpy(ret,string,strlen(string)+1);
    return ret;
}

/*
 *  The SkStrAppend... methods will write into the provided buffer, assuming it is large enough.
 *  Each method has an associated const (e.g. SkStrAppendU32_MaxSize) which will be the largest
 *  value needed for that method's buffer.
 *
 *  char storage[SkStrAppendU32_MaxSize];
 *  SkStrAppendU32(storage, value);
 *
 *  Note : none of the SkStrAppend... methods write a terminating 0 to their buffers. Instead,
 *  the methods return the ptr to the end of the written part of the buffer. This can be used
 *  to compute the length, and/or know where to write a 0 if that is desired.
 *
 *  char storage[SkStrAppendU32_MaxSize + 1];
 *  char* stop = SkStrAppendU32(storage, value);
 *  size_t len = stop - storage;
 *  *stop = 0;   // valid, since storage was 1 byte larger than the max.
 */

#define SkStrAppendU32_MaxSize  10
char*   SkStrAppendU32(char buffer[], uint32_t);
#define SkStrAppendU64_MaxSize  20
char*   SkStrAppendU64(char buffer[], uint64_t, int minDigits);

#define SkStrAppendS32_MaxSize  (SkStrAppendU32_MaxSize + 1)
char*   SkStrAppendS32(char buffer[], int32_t);
#define SkStrAppendS64_MaxSize  (SkStrAppendU64_MaxSize + 1)
char*   SkStrAppendS64(char buffer[], int64_t, int minDigits);

/**
 *  Floats have at most 8 significant digits, so we limit our %g to that.
 *  However, the total string could be 15 characters: -1.2345678e-005
 *
 *  In theory we should only expect up to 2 digits for the exponent, but on
 *  some platforms we have seen 3 (as in the example above).
 */
#define SkStrAppendScalar_MaxSize  15

/**
 *  Write the scaler in decimal format into buffer, and return a pointer to
 *  the next char after the last one written. Note: a terminating 0 is not
 *  written into buffer, which must be at least SkStrAppendScalar_MaxSize.
 *  Thus if the caller wants to add a 0 at the end, buffer must be at least
 *  SkStrAppendScalar_MaxSize + 1 bytes large.
 */
#define SkStrAppendScalar SkStrAppendFloat

char* SkStrAppendFloat(char buffer[], float);

/** \class SkString

    Light weight class for managing strings. Uses reference
    counting to make string assignments and copies very fast
    with no extra RAM cost. Assumes UTF8 encoding.
*/
class SK_API SkString {
public:
                SkString();
    explicit    SkString(size_t len);
    explicit    SkString(const char text[]);
                SkString(const char text[], size_t len);
                SkString(const SkString&);
                SkString(SkString&&);
    explicit    SkString(const std::string&);
                ~SkString();

    bool        isEmpty() const { return 0 == fRec->fLength; }
    size_t      size() const { return (size_t) fRec->fLength; }
    const char* c_str() const { return fRec->data(); }
    char operator[](size_t n) const { return this->c_str()[n]; }

    bool equals(const SkString&) const;
    bool equals(const char text[]) const;
    bool equals(const char text[], size_t len) const;

    bool startsWith(const char prefixStr[]) const {
        return SkStrStartsWith(fRec->data(), prefixStr);
    }
    bool startsWith(const char prefixChar) const {
        return SkStrStartsWith(fRec->data(), prefixChar);
    }
    bool endsWith(const char suffixStr[]) const {
        return SkStrEndsWith(fRec->data(), suffixStr);
    }
    bool endsWith(const char suffixChar) const {
        return SkStrEndsWith(fRec->data(), suffixChar);
    }
    bool contains(const char substring[]) const {
        return SkStrContains(fRec->data(), substring);
    }
    bool contains(const char subchar) const {
        return SkStrContains(fRec->data(), subchar);
    }
    int find(const char substring[]) const {
        return SkStrFind(fRec->data(), substring);
    }
    int findLastOf(const char subchar) const {
        return SkStrFindLastOf(fRec->data(), subchar);
    }

    friend bool operator==(const SkString& a, const SkString& b) {
        return a.equals(b);
    }
    friend bool operator!=(const SkString& a, const SkString& b) {
        return !a.equals(b);
    }

    // these methods edit the string

    SkString& operator=(const SkString&);
    SkString& operator=(SkString&&);
    SkString& operator=(const char text[]);

    char* writable_str();
    char& operator[](size_t n) { return this->writable_str()[n]; }

    void reset();
    /** String contents are preserved on resize. (For destructive resize, `set(nullptr, length)`.)
     * `resize` automatically reserves an extra byte at the end of the buffer for a null terminator.
     */
    void resize(size_t len);
    void set(const SkString& src) { *this = src; }
    void set(const char text[]);
    void set(const char text[], size_t len);

    void insert(size_t offset, const SkString& src) { this->insert(offset, src.c_str(), src.size()); }
    void insert(size_t offset, const char text[]);
    void insert(size_t offset, const char text[], size_t len);
    void insertUnichar(size_t offset, SkUnichar);
    void insertS32(size_t offset, int32_t value);
    void insertS64(size_t offset, int64_t value, int minDigits = 0);
    void insertU32(size_t offset, uint32_t value);
    void insertU64(size_t offset, uint64_t value, int minDigits = 0);
    void insertHex(size_t offset, uint32_t value, int minDigits = 0);
    void insertScalar(size_t offset, SkScalar);

    void append(const SkString& str) { this->insert((size_t)-1, str); }
    void append(const char text[]) { this->insert((size_t)-1, text); }
    void append(const char text[], size_t len) { this->insert((size_t)-1, text, len); }
    void appendUnichar(SkUnichar uni) { this->insertUnichar((size_t)-1, uni); }
    void appendS32(int32_t value) { this->insertS32((size_t)-1, value); }
    void appendS64(int64_t value, int minDigits = 0) { this->insertS64((size_t)-1, value, minDigits); }
    void appendU32(uint32_t value) { this->insertU32((size_t)-1, value); }
    void appendU64(uint64_t value, int minDigits = 0) { this->insertU64((size_t)-1, value, minDigits); }
    void appendHex(uint32_t value, int minDigits = 0) { this->insertHex((size_t)-1, value, minDigits); }
    void appendScalar(SkScalar value) { this->insertScalar((size_t)-1, value); }

    void prepend(const SkString& str) { this->insert(0, str); }
    void prepend(const char text[]) { this->insert(0, text); }
    void prepend(const char text[], size_t len) { this->insert(0, text, len); }
    void prependUnichar(SkUnichar uni) { this->insertUnichar(0, uni); }
    void prependS32(int32_t value) { this->insertS32(0, value); }
    void prependS64(int32_t value, int minDigits = 0) { this->insertS64(0, value, minDigits); }
    void prependHex(uint32_t value, int minDigits = 0) { this->insertHex(0, value, minDigits); }
    void prependScalar(SkScalar value) { this->insertScalar((size_t)-1, value); }

    void printf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
    void printVAList(const char format[], va_list);
    void appendf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
    void appendVAList(const char format[], va_list);
    void prependf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
    void prependVAList(const char format[], va_list);

    void remove(size_t offset, size_t length);

    SkString& operator+=(const SkString& s) { this->append(s); return *this; }
    SkString& operator+=(const char text[]) { this->append(text); return *this; }
    SkString& operator+=(const char c) { this->append(&c, 1); return *this; }

    /**
     *  Swap contents between this and other. This function is guaranteed
     *  to never fail or throw.
     */
    void swap(SkString& other);

private:
    struct Rec {
    public:
        constexpr Rec(uint32_t len, int32_t refCnt) : fLength(len), fRefCnt(refCnt) {}
        static sk_sp<Rec> Make(const char text[], size_t len);
        char* data() { return &fBeginningOfData; }
        const char* data() const { return &fBeginningOfData; }
        void ref() const;
        void unref() const;
        bool unique() const;

        uint32_t fLength; // logically size_t, but we want it to stay 32 bits
        mutable std::atomic<int32_t> fRefCnt;
        char fBeginningOfData = '\0';

    private:
        // Ensure the unsized delete is called.
        void operator delete(void* p) { ::operator delete(p); }
    };
    sk_sp<Rec> fRec;

#ifdef SK_DEBUG
    const SkString& validate() const;
#else
    const SkString& validate() const { return *this; }
#endif

    static const Rec gEmptyRec;
};

/// Creates a new string and writes into it using a printf()-style format.
SkString SkStringPrintf(const char* format, ...) SK_PRINTF_LIKE(1, 2);
/// This makes it easier to write a caller as a VAR_ARGS function where the format string is
/// optional.
static inline SkString SkStringPrintf() { return SkString(); }

static inline void swap(SkString& a, SkString& b) {
    a.swap(b);
}

enum SkStrSplitMode {
    // Strictly return all results. If the input is ",," and the separator is ',' this will return
    // an array of three empty strings.
    kStrict_SkStrSplitMode,

    // Only nonempty results will be added to the results. Multiple separators will be
    // coalesced. Separators at the beginning and end of the input will be ignored.  If the input is
    // ",," and the separator is ',', this will return an empty vector.
    kCoalesce_SkStrSplitMode
};

// Split str on any characters in delimiters into out.  (Think, strtok with a sane API.)
void SkStrSplit(const char* str, const char* delimiters, SkStrSplitMode splitMode,
                SkTArray<SkString>* out);
inline void SkStrSplit(const char* str, const char* delimiters, SkTArray<SkString>* out) {
    SkStrSplit(str, delimiters, kCoalesce_SkStrSplitMode, out);
}

#endif
