//
// FLBase.h
//
// Copyright 2016-Present Couchbase, Inc.
//
// Use of this software is governed by the Business Source License included
// in the file licenses/BSL-Couchbase.txt.  As of the Change Date specified
// in that file, in accordance with the Business Source License, use of this
// software will be governed by the Apache License, Version 2.0, included in
// the file licenses/APL2.txt.
//

#pragma once
#ifndef _FLBASE_H
#define _FLBASE_H

#include "CompilerSupport.h"
#include "FLSlice.h"

FL_ASSUME_NONNULL_BEGIN

#ifdef __cplusplus
extern "C" {
#endif

    // This is the C API! For the C++ API, see Fleece.hh.


    //====== BASIC TYPES

    /** \defgroup types    Basic Fleece Data Types
        @{ */

#ifndef FL_IMPL
    typedef const struct _FLValue* FLValue;         ///< A reference to a value of any type.
    typedef const struct _FLArray* FLArray;         ///< A reference to an array value.
    typedef const struct _FLDict*  FLDict;          ///< A reference to a dictionary (map) value.
    typedef struct _FLSlot*        FLSlot;          ///< A reference to a mutable array/dict item
    typedef struct _FLArray*       FLMutableArray;  ///< A reference to a mutable array.
    typedef struct _FLDict*        FLMutableDict;   ///< A reference to a mutable dictionary.
    typedef struct _FLEncoder*     FLEncoder;       ///< A reference to an encoder.
    typedef struct _FLDoc*         FLDoc;           ///< A reference to a document.
    typedef struct _FLSharedKeys*  FLSharedKeys;    ///< A reference to a shared-keys mapping.
#endif


    /** Error codes returned from some API calls. */
    typedef enum {
        kFLNoError = 0,
        kFLMemoryError,        // Out of memory, or allocation failed
        kFLOutOfRange,         // Array index or iterator out of range
        kFLInvalidData,        // Bad input data (NaN, non-string key, etc.)
        kFLEncodeError,        // Structural error encoding (missing value, too many ends, etc.)
        kFLJSONError,          // Error parsing JSON
        kFLUnknownValue,       // Unparseable data in a Value (corrupt? Or from some distant future?)
        kFLInternalError,      // Something that shouldn't happen
        kFLNotFound,           // Key not found
        kFLSharedKeysStateError, // Misuse of shared keys (not in transaction, etc.)
        kFLPOSIXError,
        kFLUnsupported,         // Operation is unsupported
    } FLError;


    /** Specifies whether not input data is trusted to be 100% valid Fleece. */
    typedef enum {
        /** Input data is not trusted to be valid, and will be fully validated by the API call. */
        kFLUntrusted,
        /** Input data is trusted to be valid. The API will perform only minimal validation when
            reading it. This is faster than kFLUntrusted, but should only be used if
            the data was generated by a trusted encoder and has not been altered or corrupted. For
            example, this can be used to parse Fleece data previously stored by your code in local
            storage.
            If invalid data is read by this call, subsequent calls to Value accessor functions can
            crash or return bogus results (including data from arbitrary memory locations.) */
        kFLTrusted,
        _kFLTrustInternalUseOnly = -1
    } FLTrust;


    //====== TIMESTAMPS


    /** \name Timestamps
         @{
            Fleece does not have a native type for dates or times; like JSON, they are represented
            as strings in ISO-8601 format, which look like "2008-08-07T05:18:51.589Z".

            They can also be represented more compactly as numbers, interpreted as milliseconds
            since the Unix epoch (midnight at January 1 1970, UTC.)
     */

    /** A point in time, expressed as milliseconds since the Unix epoch (1-1-1970 midnight UTC.) */
    typedef int64_t FLTimestamp;

    /** A value representing a missing timestamp; returned when a date cannot be parsed. */
    #define FLTimestampNone INT64_MIN

    /** Returns an FLTimestamp corresponding to the current time. */
    FLEECE_PUBLIC FLTimestamp FLTimestamp_Now(void) FLAPI;

    /** Formats a timestamp as a date-time string in ISO-8601 format.
        @note  See also \ref FLEncoder_WriteDateString, which writes a timestamp to an `FLEncoder`.
        @param timestamp  A time, given as milliseconds since the Unix epoch (1/1/1970 00:00 UTC.)
        @param asUTC  If true, the timestamp will be given in universal time; if false, in the
                      local timezone.
        @return  A heap-allocated string, which you are responsible for releasing. */
    FLEECE_PUBLIC FLStringResult FLTimestamp_ToString(FLTimestamp timestamp, bool asUTC) FLAPI;

    /** Parses an ISO-8601 date-time string to a timestamp. On failure returns `FLTimestampNone`.
        @note  See also \ref FLValue_AsTimestamp, which takes an `FLValue` and interprets numeric
        representations as well as strings. */
    FLEECE_PUBLIC FLTimestamp FLTimestamp_FromString(FLString str) FLAPI;

    /** @} */

    /** @} */

#ifdef __cplusplus
}
#endif

FL_ASSUME_NONNULL_END

#endif // _FLBASE_H
