/*
 * Copyright (c) 2016,2017 DeNA Co., Ltd., Kazuho Oku, Fastly
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */
#ifndef util_h
#define util_h

#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 700 /* required for glibc to use getaddrinfo, etc. */
#endif

#include <errno.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include <openssl/pem.h>
#include "picotls/pembase64.h"
#include "picotls/openssl.h"

static inline void load_certificate_chain(ptls_context_t *ctx, const char *fn)
{
    if (ptls_load_certificates(ctx, (char *)fn) != 0) {
        fprintf(stderr, "failed to load certificate:%s:%s\n", fn, strerror(errno));
        exit(1);
    }
}

static inline void load_raw_public_key(ptls_iovec_t *raw_public_key, char const *cert_pem_file)
{
    size_t count;
    if (ptls_load_pem_objects(cert_pem_file, "PUBLIC KEY", raw_public_key, 1, &count) != 0) {
        fprintf(stderr, "failed to load public key:%s:%s\n", cert_pem_file, strerror(errno));
        exit(1);
    }
}

static inline void load_private_key(ptls_context_t *ctx, const char *fn)
{
    static ptls_openssl_sign_certificate_t sc;
    FILE *fp;
    EVP_PKEY *pkey;

    if ((fp = fopen(fn, "rb")) == NULL) {
        fprintf(stderr, "failed to open file:%s:%s\n", fn, strerror(errno));
        exit(1);
    }
    pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
    fclose(fp);

    if (pkey == NULL) {
        fprintf(stderr, "failed to read private key from file:%s\n", fn);
        exit(1);
    }

    ptls_openssl_init_sign_certificate(&sc, pkey);
    EVP_PKEY_free(pkey);

    ctx->sign_certificate = &sc.super;
}

struct st_util_save_ticket_t {
    ptls_save_ticket_t super;
    char fn[MAXPATHLEN];
};

static int util_save_ticket_cb(ptls_save_ticket_t *_self, ptls_t *tls, ptls_iovec_t src)
{
    struct st_util_save_ticket_t *self = (struct st_util_save_ticket_t *)_self;
    FILE *fp;

    if ((fp = fopen(self->fn, "wb")) == NULL) {
        fprintf(stderr, "failed to open file:%s:%s\n", self->fn, strerror(errno));
        return PTLS_ERROR_LIBRARY;
    }
    fwrite(src.base, 1, src.len, fp);
    fclose(fp);

    return 0;
}

static inline void setup_session_file(ptls_context_t *ctx, ptls_handshake_properties_t *hsprop, const char *fn)
{
    static struct st_util_save_ticket_t st;
    FILE *fp;

    /* setup save_ticket callback */
    strcpy(st.fn, fn);
    st.super.cb = util_save_ticket_cb;
    ctx->save_ticket = &st.super;

    /* load session ticket if possible */
    if ((fp = fopen(fn, "rb")) != NULL) {
        static uint8_t ticket[16384];
        size_t ticket_size = fread(ticket, 1, sizeof(ticket), fp);
        if (ticket_size == 0 || !feof(fp)) {
            fprintf(stderr, "failed to load ticket from file:%s\n", fn);
            exit(1);
        }
        fclose(fp);
        hsprop->client.session_ticket = ptls_iovec_init(ticket, ticket_size);
    }
}

static inline X509_STORE *init_cert_store(char const *crt_file)
{
    int ret = 0;
    X509_STORE *store = X509_STORE_new();

    if (store != NULL) {
        X509_LOOKUP *lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
        ret = X509_LOOKUP_load_file(lookup, crt_file, X509_FILETYPE_PEM);
        if (ret != 1) {
            fprintf(stderr, "Cannot load store (%s), ret = %d\n", crt_file, ret);
            X509_STORE_free(store);
            exit(1);
        }
    } else {
        fprintf(stderr, "Cannot get a new X509 store\n");
        exit(1);
    }

    return store;
}

static inline void setup_verify_certificate(ptls_context_t *ctx, const char *ca_file)
{
    static ptls_openssl_verify_certificate_t vc;
    ptls_openssl_init_verify_certificate(&vc, ca_file != NULL ? init_cert_store(ca_file) : NULL);
    ctx->verify_certificate = &vc.super;
}

static inline void setup_raw_pubkey_verify_certificate(ptls_context_t *ctx, EVP_PKEY *pubkey)
{
    static ptls_openssl_raw_pubkey_verify_certificate_t vc;
    ptls_openssl_raw_pubkey_init_verify_certificate(&vc, pubkey);
    ctx->verify_certificate = &vc.super;
}

struct st_util_log_event_t {
    ptls_log_event_t super;
    FILE *fp;
};

static void log_event_cb(ptls_log_event_t *_self, ptls_t *tls, const char *type, const char *fmt, ...)
{
    struct st_util_log_event_t *self = (struct st_util_log_event_t *)_self;
    char randomhex[PTLS_HELLO_RANDOM_SIZE * 2 + 1];
    va_list args;

    ptls_hexdump(randomhex, ptls_get_client_random(tls).base, PTLS_HELLO_RANDOM_SIZE);
    fprintf(self->fp, "%s %s ", type, randomhex);

    va_start(args, fmt);
    vfprintf(self->fp, fmt, args);
    va_end(args);

    fprintf(self->fp, "\n");
    fflush(self->fp);
}

static inline void setup_log_event(ptls_context_t *ctx, const char *fn)
{
    static struct st_util_log_event_t ls;

    if ((ls.fp = fopen(fn, "at")) == NULL) {
        fprintf(stderr, "failed to open file:%s:%s\n", fn, strerror(errno));
        exit(1);
    }
    ls.super.cb = log_event_cb;
    ctx->log_event = &ls.super;
}

/* single-entry session cache */
struct st_util_session_cache_t {
    ptls_encrypt_ticket_t super;
    uint8_t id[32];
    ptls_iovec_t data;
};

static int encrypt_ticket_cb(ptls_encrypt_ticket_t *_self, ptls_t *tls, int is_encrypt, ptls_buffer_t *dst, ptls_iovec_t src)
{
    struct st_util_session_cache_t *self = (struct st_util_session_cache_t *)_self;
    int ret;

    if (is_encrypt) {

        /* replace the cached entry along with a newly generated session id */
        free(self->data.base);
        if ((self->data.base = (uint8_t *)malloc(src.len)) == NULL)
            return PTLS_ERROR_NO_MEMORY;

        ptls_get_context(tls)->random_bytes(self->id, sizeof(self->id));
        memcpy(self->data.base, src.base, src.len);
        self->data.len = src.len;

        /* store the session id in buffer */
        if ((ret = ptls_buffer_reserve(dst, sizeof(self->id))) != 0)
            return ret;
        memcpy(dst->base + dst->off, self->id, sizeof(self->id));
        dst->off += sizeof(self->id);

    } else {

        /* check if session id is the one stored in cache */
        if (src.len != sizeof(self->id))
            return PTLS_ERROR_SESSION_NOT_FOUND;
        if (memcmp(self->id, src.base, sizeof(self->id)) != 0)
            return PTLS_ERROR_SESSION_NOT_FOUND;

        /* return the cached value */
        if ((ret = ptls_buffer_reserve(dst, self->data.len)) != 0)
            return ret;
        memcpy(dst->base + dst->off, self->data.base, self->data.len);
        dst->off += self->data.len;
    }

    return 0;
}

static inline void setup_session_cache(ptls_context_t *ctx)
{
    static struct st_util_session_cache_t sc;

    sc.super.cb = encrypt_ticket_cb;

    ctx->ticket_lifetime = 86400;
    ctx->max_early_data_size = 8192;
    ctx->encrypt_ticket = &sc.super;
}

static struct {
    ptls_iovec_t config_list;
    struct {
        struct {
            ptls_hpke_kem_t *kem;
            ptls_key_exchange_context_t *ctx;
        } list[16];
        size_t count;
    } keyex;
    struct {
        ptls_iovec_t configs;
        char *fn;
    } retry;
} ech;

static ptls_aead_context_t *ech_create_opener(ptls_ech_create_opener_t *self, ptls_hpke_kem_t **kem,
                                              ptls_hpke_cipher_suite_t **cipher, ptls_t *tls, uint8_t config_id,
                                              ptls_hpke_cipher_suite_id_t cipher_id, ptls_iovec_t enc, ptls_iovec_t info_prefix)
{
    const uint8_t *src = ech.config_list.base, *const end = src + ech.config_list.len;
    size_t index = 0;
    int ret = 0;

    /* look for the cipher implementation; this should better be specific to each ECHConfig (as each of them may advertise different
     * set of values) */
    *cipher = NULL;
    for (size_t i = 0; ptls_openssl_hpke_cipher_suites[i] != NULL; ++i) {
        if (ptls_openssl_hpke_cipher_suites[i]->id.kdf == cipher_id.kdf &&
            ptls_openssl_hpke_cipher_suites[i]->id.aead == cipher_id.aead) {
            *cipher = ptls_openssl_hpke_cipher_suites[i];
            break;
        }
    }
    if (*cipher == NULL)
        goto Exit;

    ptls_decode_open_block(src, end, 2, {
        uint16_t version;
        if ((ret = ptls_decode16(&version, &src, end)) != 0)
            goto Exit;
        do {
            ptls_decode_open_block(src, end, 2, {
                if (src == end) {
                    ret = PTLS_ALERT_DECODE_ERROR;
                    goto Exit;
                }
                if (*src == config_id) {
                    /* this is the ECHConfig that we have been looking for */
                    if (index >= ech.keyex.count) {
                        fprintf(stderr, "ECH key missing for config %zu\n", index);
                        return NULL;
                    }
                    uint8_t *info = malloc(info_prefix.len + end - (src - 4));
                    memcpy(info, info_prefix.base, info_prefix.len);
                    memcpy(info + info_prefix.len, src - 4, end - (src - 4));
                    ptls_aead_context_t *aead;
                    ptls_hpke_setup_base_r(ech.keyex.list[index].kem, *cipher, ech.keyex.list[index].ctx, &aead, enc,
                                           ptls_iovec_init(info, info_prefix.len + end - (src - 4)));
                    free(info);
                    *kem = ech.keyex.list[index].kem;
                    return aead;
                }
                ++index;
                src = end;
            });
        } while (src != end);
    });

Exit:
    if (ret != 0)
        fprintf(stderr, "ECH decode error:%d\n", ret);
    return NULL;
}

static void ech_save_retry_configs(void)
{
    if (ech.retry.configs.base == NULL)
        return;

    FILE *fp;
    if ((fp = fopen(ech.retry.fn, "wt")) == NULL) {
        fprintf(stderr, "failed to write to ECH config file:%s:%s\n", ech.retry.fn, strerror(errno));
        exit(1);
    }
    fwrite(ech.retry.configs.base, 1, ech.retry.configs.len, fp);
    fclose(fp);
}

static void ech_setup_configs(const char *fn)
{
    FILE *fp;

    if ((fp = fopen(fn, "rt")) == NULL) {
        fprintf(stderr, "failed to open ECHConfigList file:%s:%s\n", fn, strerror(errno));
        exit(1);
    }
    ech.config_list.base = malloc(65536);
    if ((ech.config_list.len = fread(ech.config_list.base, 1, 65536, fp)) == 65536) {
        fprintf(stderr, "ECHConfigList is too large:%s\n", fn);
        exit(1);
    }
    fclose(fp);
    ech.retry.fn = strdup(fn);
}

static void ech_setup_key(ptls_context_t *ctx, const char *fn)
{
    FILE *fp;
    EVP_PKEY *pkey;
    int ret;

    if ((fp = fopen(fn, "rt")) == NULL) {
        fprintf(stderr, "failed to open ECH private key file:%s:%s\n", fn, strerror(errno));
        exit(1);
    }
    if ((pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL)) == NULL) {
        fprintf(stderr, "failed to load private key from file:%s\n", fn);
        exit(1);
    }
    if ((ret = ptls_openssl_create_key_exchange(&ech.keyex.list[ech.keyex.count].ctx, pkey)) != 0) {
        fprintf(stderr, "failed to load private key from file:%s:picotls-error:%d", fn, ret);
        exit(1);
    }
    EVP_PKEY_free(pkey);
    fclose(fp);

    for (size_t i = 0; ptls_openssl_hpke_kems[i] != NULL; ++i) {
        if (ptls_openssl_hpke_kems[i]->keyex == ech.keyex.list[ech.keyex.count].ctx->algo) {
            ech.keyex.list[ech.keyex.count].kem = ptls_openssl_hpke_kems[i];
            break;
        }
    }
    if (ech.keyex.list[ech.keyex.count].kem == NULL) {
        fprintf(stderr, "kem unknown for private key:%s\n", fn);
        exit(1);
    }

    ++ech.keyex.count;

    static ptls_ech_create_opener_t opener = {.cb = ech_create_opener};
    ctx->ech.server.create_opener = &opener;
}

static inline int resolve_address(struct sockaddr *sa, socklen_t *salen, const char *host, const char *port, int family, int type,
                                  int proto)
{
    struct addrinfo hints, *res;
    int err;

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = family;
    hints.ai_socktype = type;
    hints.ai_protocol = proto;
    hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV | AI_PASSIVE;
    if ((err = getaddrinfo(host, port, &hints, &res)) != 0 || res == NULL) {
        fprintf(stderr, "failed to resolve address:%s:%s:%s\n", host, port,
                err != 0 ? gai_strerror(err) : "getaddrinfo returned NULL");
        return -1;
    }

    memcpy(sa, res->ai_addr, res->ai_addrlen);
    *salen = res->ai_addrlen;

    freeaddrinfo(res);
    return 0;
}

static inline int normalize_txt(uint8_t *p, size_t len)
{
    uint8_t *const end = p + len, *dst = p;

    if (p == end)
        return 0;

    do {
        size_t block_len = *p++;
        if (end - p < block_len)
            return 0;
        memmove(dst, p, block_len);
        dst += block_len;
        p += block_len;
    } while (p != end);
    *dst = '\0';

    return 1;
}

/* The ptls_repeat_while_eintr macro will repeat a function call (block) if it is interrupted (EINTR) before completion. If failing
 * for other reason, the macro executes the exit block, such as either { break; } or { goto Fail; }.
 */
#ifdef _WINDOWS
#define repeat_while_eintr(expr, exit_block)                                                                                       \
    while ((expr) < 0) {                                                                                                           \
        exit_block;                                                                                                                \
    }
#else
#define repeat_while_eintr(expr, exit_block)                                                                                       \
    while ((expr) < 0) {                                                                                                           \
        if (errno == EINTR)                                                                                                        \
            continue;                                                                                                              \
        exit_block;                                                                                                                \
    }
#endif

#endif
