/**
 * Synor Compiler SDK for C
 *
 * Smart contract compilation, optimization, and ABI generation.
 */

#ifndef SYNOR_COMPILER_H
#define SYNOR_COMPILER_H

#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

/* ============================================================================
 * Opaque Types
 * ============================================================================ */

typedef struct synor_compiler_client synor_compiler_client_t;
typedef struct synor_compilation_result synor_compilation_result_t;
typedef struct synor_contract_abi synor_contract_abi_t;
typedef struct synor_contract_analysis synor_contract_analysis_t;
typedef struct synor_validation_result synor_validation_result_t;

/* ============================================================================
 * Enumerations
 * ============================================================================ */

/** Optimization level */
typedef enum {
    SYNOR_COMPILER_OPT_NONE = 0,       /**< No optimization */
    SYNOR_COMPILER_OPT_BASIC = 1,      /**< Basic optimizations (stripping only) */
    SYNOR_COMPILER_OPT_SIZE = 2,       /**< Optimize for size (-Os equivalent) */
    SYNOR_COMPILER_OPT_AGGRESSIVE = 3  /**< Aggressive optimization (-O3 -Os equivalent) */
} synor_compiler_optimization_level_t;

/** Error codes */
typedef enum {
    SYNOR_COMPILER_OK = 0,
    SYNOR_COMPILER_ERROR_INVALID_ARGUMENT = 1,
    SYNOR_COMPILER_ERROR_NETWORK = 2,
    SYNOR_COMPILER_ERROR_AUTH = 3,
    SYNOR_COMPILER_ERROR_NOT_FOUND = 4,
    SYNOR_COMPILER_ERROR_TIMEOUT = 5,
    SYNOR_COMPILER_ERROR_INTERNAL = 6,
    SYNOR_COMPILER_ERROR_CLIENT_CLOSED = 7,
    SYNOR_COMPILER_ERROR_PARSE = 8,
    SYNOR_COMPILER_ERROR_VALIDATION = 9,
    SYNOR_COMPILER_ERROR_OPTIMIZATION = 10,
    SYNOR_COMPILER_ERROR_CONTRACT_TOO_LARGE = 11
} synor_compiler_error_t;

/* ============================================================================
 * Structures
 * ============================================================================ */

/** Strip options */
typedef struct {
    bool strip_debug;        /**< Strip debug sections */
    bool strip_producers;    /**< Strip producer sections */
    bool strip_names;        /**< Strip name sections */
    bool strip_custom;       /**< Strip custom sections */
    const char** preserve_sections;  /**< Sections to preserve */
    size_t preserve_sections_count;
    bool strip_unused;       /**< Strip unused functions */
} synor_compiler_strip_options_t;

/** Compiler configuration */
typedef struct {
    const char* api_key;
    const char* endpoint;               /**< Default: "https://compiler.synor.io/v1" */
    uint32_t timeout_ms;                /**< Default: 60000 */
    uint32_t retries;                   /**< Default: 3 */
    synor_compiler_optimization_level_t optimization_level;  /**< Default: SIZE */
    synor_compiler_strip_options_t* strip_options;  /**< Optional */
    size_t max_contract_size;           /**< Default: 262144 (256 KB) */
    bool use_wasm_opt;                  /**< Default: true */
    bool validate;                      /**< Default: true */
    bool extract_metadata;              /**< Default: true */
    bool generate_abi;                  /**< Default: true */
    bool debug;                         /**< Default: false */
} synor_compiler_config_t;

/** Compilation request */
typedef struct {
    synor_compiler_optimization_level_t* optimization_level;  /**< Optional */
    synor_compiler_strip_options_t* strip_options;  /**< Optional */
    bool* use_wasm_opt;     /**< Optional */
    bool* validate;         /**< Optional */
    bool* extract_metadata; /**< Optional */
    bool* generate_abi;     /**< Optional */
} synor_compiler_request_t;

/** Validation error */
typedef struct {
    char code[64];
    char message[256];
    char* location;  /**< Optional */
} synor_compiler_validation_error_t;

/** Contract metadata */
typedef struct {
    char* name;         /**< Optional */
    char* version;      /**< Optional */
    char** authors;
    size_t authors_count;
    char* description;  /**< Optional */
    char* license;      /**< Optional */
    char* repository;   /**< Optional */
    uint64_t build_timestamp;
    char* rust_version; /**< Optional */
    char* sdk_version;  /**< Optional */
} synor_compiler_metadata_t;

/** Compilation result info */
typedef struct {
    char contract_id[64];
    char code_hash[66];
    size_t original_size;
    size_t optimized_size;
    double size_reduction;
    uint64_t estimated_deploy_gas;
    bool validation_valid;
    size_t warning_count;
} synor_compiler_result_info_t;

/** Function ABI */
typedef struct {
    char name[128];
    char selector[10];  /* 4 bytes hex + null */
    size_t input_count;
    size_t output_count;
    bool view;
    bool payable;
    char* doc;
} synor_compiler_function_abi_t;

/** ABI info */
typedef struct {
    char name[128];
    char version[32];
    size_t function_count;
    size_t event_count;
    size_t error_count;
} synor_compiler_abi_info_t;

/** Size breakdown */
typedef struct {
    size_t code;
    size_t data;
    size_t types;
    size_t functions;
    size_t memory;
    size_t table;
    size_t exports;
    size_t imports;
    size_t custom;
    size_t total;
} synor_compiler_size_breakdown_t;

/** Security issue */
typedef struct {
    char severity[16];  /* low, medium, high, critical */
    char type[64];
    char description[256];
    char* location;
} synor_compiler_security_issue_t;

/** Security analysis */
typedef struct {
    int score;  /* 0-100 */
    synor_compiler_security_issue_t* issues;
    size_t issue_count;
    char** recommendations;
    size_t recommendation_count;
} synor_compiler_security_analysis_t;

/* ============================================================================
 * Client Lifecycle
 * ============================================================================ */

/**
 * Create a new compiler client
 *
 * @param config Configuration options
 * @return New client handle, or NULL on error
 */
synor_compiler_client_t* synor_compiler_client_new(const synor_compiler_config_t* config);

/**
 * Close and free a client
 *
 * @param client Client to close
 */
void synor_compiler_client_free(synor_compiler_client_t* client);

/**
 * Check if client is closed
 *
 * @param client Client handle
 * @return true if closed
 */
bool synor_compiler_client_is_closed(const synor_compiler_client_t* client);

/**
 * Health check
 *
 * @param client Client handle
 * @param healthy Output parameter for health status
 * @return Error code
 */
synor_compiler_error_t synor_compiler_health_check(synor_compiler_client_t* client, bool* healthy);

/* ============================================================================
 * Compilation Operations
 * ============================================================================ */

/**
 * Compile WASM bytecode
 *
 * @param client Client handle
 * @param wasm WASM bytecode
 * @param wasm_len Length of WASM bytecode
 * @param request Optional compilation request parameters
 * @param result Output parameter for compilation result
 * @return Error code
 */
synor_compiler_error_t synor_compiler_compile(
    synor_compiler_client_t* client,
    const uint8_t* wasm,
    size_t wasm_len,
    const synor_compiler_request_t* request,
    synor_compilation_result_t** result
);

/**
 * Get compilation result info
 *
 * @param result Compilation result handle
 * @param info Output parameter for result info
 * @return Error code
 */
synor_compiler_error_t synor_compiler_result_get_info(
    const synor_compilation_result_t* result,
    synor_compiler_result_info_t* info
);

/**
 * Get optimized bytecode from result
 *
 * @param result Compilation result handle
 * @param code Output buffer for bytecode
 * @param code_len Input: buffer size, Output: actual bytecode length
 * @return Error code
 */
synor_compiler_error_t synor_compiler_result_get_code(
    const synor_compilation_result_t* result,
    uint8_t* code,
    size_t* code_len
);

/**
 * Get metadata from result
 *
 * @param result Compilation result handle
 * @param metadata Output parameter for metadata
 * @return Error code
 */
synor_compiler_error_t synor_compiler_result_get_metadata(
    const synor_compilation_result_t* result,
    synor_compiler_metadata_t* metadata
);

/**
 * Free compilation result
 *
 * @param result Result to free
 */
void synor_compiler_result_free(synor_compilation_result_t* result);

/* ============================================================================
 * ABI Operations
 * ============================================================================ */

/**
 * Extract ABI from WASM bytecode
 *
 * @param client Client handle
 * @param wasm WASM bytecode
 * @param wasm_len Length of WASM bytecode
 * @param abi Output parameter for ABI
 * @return Error code
 */
synor_compiler_error_t synor_compiler_abi_extract(
    synor_compiler_client_t* client,
    const uint8_t* wasm,
    size_t wasm_len,
    synor_contract_abi_t** abi
);

/**
 * Get ABI info
 *
 * @param abi ABI handle
 * @param info Output parameter for ABI info
 * @return Error code
 */
synor_compiler_error_t synor_compiler_abi_get_info(
    const synor_contract_abi_t* abi,
    synor_compiler_abi_info_t* info
);

/**
 * Get function from ABI by index
 *
 * @param abi ABI handle
 * @param index Function index
 * @param func Output parameter for function
 * @return Error code
 */
synor_compiler_error_t synor_compiler_abi_get_function(
    const synor_contract_abi_t* abi,
    size_t index,
    synor_compiler_function_abi_t* func
);

/**
 * Find function by name
 *
 * @param abi ABI handle
 * @param name Function name
 * @param func Output parameter for function (NULL if not found)
 * @return Error code
 */
synor_compiler_error_t synor_compiler_abi_find_function(
    const synor_contract_abi_t* abi,
    const char* name,
    synor_compiler_function_abi_t* func
);

/**
 * Free ABI
 *
 * @param abi ABI to free
 */
void synor_compiler_abi_free(synor_contract_abi_t* abi);

/* ============================================================================
 * Analysis Operations
 * ============================================================================ */

/**
 * Analyze WASM bytecode
 *
 * @param client Client handle
 * @param wasm WASM bytecode
 * @param wasm_len Length of WASM bytecode
 * @param analysis Output parameter for analysis
 * @return Error code
 */
synor_compiler_error_t synor_compiler_analyze(
    synor_compiler_client_t* client,
    const uint8_t* wasm,
    size_t wasm_len,
    synor_contract_analysis_t** analysis
);

/**
 * Get size breakdown from analysis
 *
 * @param analysis Analysis handle
 * @param breakdown Output parameter for size breakdown
 * @return Error code
 */
synor_compiler_error_t synor_compiler_analysis_get_size_breakdown(
    const synor_contract_analysis_t* analysis,
    synor_compiler_size_breakdown_t* breakdown
);

/**
 * Get security analysis
 *
 * @param analysis Analysis handle
 * @param security Output parameter for security analysis
 * @return Error code
 */
synor_compiler_error_t synor_compiler_analysis_get_security(
    const synor_contract_analysis_t* analysis,
    synor_compiler_security_analysis_t* security
);

/**
 * Estimate deployment gas
 *
 * @param client Client handle
 * @param wasm WASM bytecode
 * @param wasm_len Length of WASM bytecode
 * @param gas Output parameter for gas estimate
 * @return Error code
 */
synor_compiler_error_t synor_compiler_estimate_deploy_gas(
    synor_compiler_client_t* client,
    const uint8_t* wasm,
    size_t wasm_len,
    uint64_t* gas
);

/**
 * Free analysis
 *
 * @param analysis Analysis to free
 */
void synor_compiler_analysis_free(synor_contract_analysis_t* analysis);

/* ============================================================================
 * Validation Operations
 * ============================================================================ */

/**
 * Validate WASM bytecode
 *
 * @param client Client handle
 * @param wasm WASM bytecode
 * @param wasm_len Length of WASM bytecode
 * @param result Output parameter for validation result
 * @return Error code
 */
synor_compiler_error_t synor_compiler_validate(
    synor_compiler_client_t* client,
    const uint8_t* wasm,
    size_t wasm_len,
    synor_validation_result_t** result
);

/**
 * Check if validation passed
 *
 * @param result Validation result handle
 * @param valid Output parameter for validity
 * @return Error code
 */
synor_compiler_error_t synor_compiler_validation_is_valid(
    const synor_validation_result_t* result,
    bool* valid
);

/**
 * Get validation error count
 *
 * @param result Validation result handle
 * @param count Output parameter for error count
 * @return Error code
 */
synor_compiler_error_t synor_compiler_validation_get_error_count(
    const synor_validation_result_t* result,
    size_t* count
);

/**
 * Get validation error by index
 *
 * @param result Validation result handle
 * @param index Error index
 * @param error Output parameter for error
 * @return Error code
 */
synor_compiler_error_t synor_compiler_validation_get_error(
    const synor_validation_result_t* result,
    size_t index,
    synor_compiler_validation_error_t* error
);

/**
 * Free validation result
 *
 * @param result Result to free
 */
void synor_compiler_validation_free(synor_validation_result_t* result);

/* ============================================================================
 * Utility Functions
 * ============================================================================ */

/**
 * Get error message
 *
 * @param error Error code
 * @return Error message string
 */
const char* synor_compiler_error_message(synor_compiler_error_t error);

/**
 * Free metadata
 *
 * @param metadata Metadata to free
 */
void synor_compiler_metadata_free(synor_compiler_metadata_t* metadata);

/**
 * Free security analysis
 *
 * @param security Security analysis to free
 */
void synor_compiler_security_free(synor_compiler_security_analysis_t* security);

/* ============================================================================
 * Constants
 * ============================================================================ */

#define SYNOR_COMPILER_MAX_CONTRACT_SIZE 262144  /* 256 KB */
#define SYNOR_COMPILER_MAX_MEMORY_PAGES 16

#ifdef __cplusplus
}
#endif

#endif /* SYNOR_COMPILER_H */
