/**
  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
 */

/**
 * @file Cleanup.h
 * @brief Easy-to-use utilities to avoid resource leaks or double-releases of resources.  Independent of the rest
 *        of the CPPAPI.
 */

#pragma once

#include <type_traits>
#include <memory>

#include <ts/ts.h>

namespace atscppapi
{
// For TS API types TSXxx with a TSXxxDestroy function, define standard deleter TSXxxDeleter, and use it to
// define TSXxxUniqPtr (specialization of std::unique_ptr).  X() is used when the destroy function returns void,
// Y() is used when the destroy function returns TSReturnCode.

#if defined(X)
#error "X defined as preprocessor symbol"
#endif

#define X(NAME_SEGMENT)               \
  struct TS##NAME_SEGMENT##Deleter {  \
    void                              \
    operator()(TS##NAME_SEGMENT ptr)  \
    {                                 \
      TS##NAME_SEGMENT##Destroy(ptr); \
    }                                 \
  };                                  \
  using TS##NAME_SEGMENT##UniqPtr = std::unique_ptr<std::remove_pointer_t<TS##NAME_SEGMENT>, TS##NAME_SEGMENT##Deleter>;

#if defined(Y)
#error "Y defined as preprocessor symbol"
#endif

#define Y(NAME_SEGMENT)                                       \
  struct TS##NAME_SEGMENT##Deleter {                          \
    void                                                      \
    operator()(TS##NAME_SEGMENT ptr)                          \
    {                                                         \
      TSAssert(TS##NAME_SEGMENT##Destroy(ptr) == TS_SUCCESS); \
    }                                                         \
  };                                                          \
  using TS##NAME_SEGMENT##UniqPtr = std::unique_ptr<std::remove_pointer_t<TS##NAME_SEGMENT>, TS##NAME_SEGMENT##Deleter>;

Y(MBuffer)       // Defines TSMBufferDeleter and TSMBufferUniqPtr.
X(MimeParser)    // Defines TSMimeParserDeleter and TSMimeParserUniqPtr.
X(Thread)        // Defines TSThreadDeleter and TSThreadUniqPtr.
X(Mutex)         // Defines TSMutexDeleter and TSMutexUniqPtr.
Y(CacheKey)      // Defines TSCacheKeyDeleter and TSCacheKeyUniqPtr.
X(Cont)          // Defines TSContDeleter and TSContUniqPtr.
X(SslContext)    // Defines TSSslContextDeleter and TSSslContextUniqPtr.
X(IOBuffer)      // Defines TSIOBufferDeleter and TSIOBufferUniqPtr.
Y(TextLogObject) // Defines TSTextLogObjectDeleter and TSTextLogObjectUniqPtr.
X(Uuid)          // Defines TSUuidDeleter and TSUuidUniqPtr.

#undef X
#undef Y

// Deleter and unique pointer for memory buffer returned by TSalloc(), TSrealloc(), Tstrdup(), TSsrtndup().
//
struct TSMemDeleter {
  void
  operator()(void *ptr)
  {
    TSfree(ptr);
  }
};
using TSMemUniqPtr = std::unique_ptr<void, TSMemDeleter>;

// Deleter and unique pointer for TSIOBufferReader.  Care must be taken that the reader is deleted before the
// TSIOBuffer to which it refers is deleted.
//
struct TSIOBufferReaderDeleter {
  void
  operator()(TSIOBufferReader ptr)
  {
    TSIOBufferReaderFree(ptr);
  }
};
using TSIOBufferReaderUniqPtr = std::unique_ptr<std::remove_pointer_t<TSIOBufferReader>, TSIOBufferReaderDeleter>;

class TxnAuxDataMgrBase
{
protected:
  struct MgrData_ {
    TSCont txnCloseContp = nullptr;
    int    txnArgIndex   = -1;
  };

public:
  class MgrData : private MgrData_
  {
    friend class TxnAuxDataMgrBase;
  };

protected:
  static MgrData_ &
  access(MgrData &md)
  {
    return md;
  }
};

using TxnAuxMgrData = TxnAuxDataMgrBase::MgrData;

// Class to manage auxiliary data for a transaction.  If an instance is created for the transaction, the instance
// will be deleted on the TXN_CLOSE transaction hook (which is always triggered for all transactions).
// The TxnAuxData class must have a public default constructor.
//
template <class TxnAuxData, TxnAuxMgrData &MDRef> class TxnAuxDataMgr : private TxnAuxDataMgrBase
{
public:
  using Data = TxnAuxData;

  // This must be called from the plugin init function.  arg_name is the name for the transaction argument used
  // to store the pointer to the auxiliary data class instance.  Repeated calls are ignored.
  //
  static void
  init(char const *arg_name, char const *arg_desc = "per-transaction auxiliary data")
  {
    MgrData_ &md = access(MDRef);

    if (md.txnArgIndex >= 0) {
      return;
    }

    TSReleaseAssert(TSUserArgIndexReserve(TS_USER_ARGS_TXN, arg_name, arg_desc, &md.txnArgIndex) == TS_SUCCESS);
    TSReleaseAssert(md.txnCloseContp = TSContCreate(_deleteAuxData, nullptr));
  }

  // Get a reference to the auxiliary data for a transaction.
  //
  static TxnAuxData &
  data(TSHttpTxn txn)
  {
    MgrData_ &md = access(MDRef);

    TSAssert(md.txnArgIndex >= 0);

    auto d = static_cast<TxnAuxData *>(TSUserArgGet(txn, md.txnArgIndex));
    if (!d) {
      d = new TxnAuxData;

      TSUserArgSet(txn, md.txnArgIndex, d);

      TSHttpTxnHookAdd(txn, TS_HTTP_TXN_CLOSE_HOOK, md.txnCloseContp);
    }
    return *d;
  }

private:
  static int
  _deleteAuxData(TSCont, TSEvent, void *edata)
  {
    MgrData_ &md = access(MDRef);

    auto txn  = static_cast<TSHttpTxn>(edata);
    auto data = static_cast<TxnAuxData *>(TSUserArgGet(txn, md.txnArgIndex));
    delete data;
    TSHttpTxnReenable(txn, TS_EVENT_HTTP_CONTINUE);
    return 0;
  };
};

} // end namespace atscppapi
