/**
 *
 * 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.
 */
#include <winmeta.h>
#include "WindowsEventLog.h"
#include "UnicodeConversion.h"
#include "utils/Deleters.h"
#include <algorithm>

#include "utils/gsl.h"

namespace org {
namespace apache {
namespace nifi {
namespace minifi {
namespace wel {

void WindowsEventLogMetadataImpl::renderMetadata() {
  DWORD status = ERROR_SUCCESS;
  DWORD dwBufferSize = 0;
  DWORD dwBufferUsed = 0;
  DWORD dwPropertyCount = 0;
  std::unique_ptr< EVT_VARIANT, utils::FreeDeleter> rendered_values;

  auto context = EvtCreateRenderContext(0, NULL, EvtRenderContextSystem);
  if (context == NULL) {
    return;
  }
  const auto contextGuard = gsl::finally([&context](){
    EvtClose(context);
  });
  if (!EvtRender(context, event_ptr_, EvtRenderEventValues, dwBufferSize, nullptr, &dwBufferUsed, &dwPropertyCount))
  {
    if (ERROR_INSUFFICIENT_BUFFER == (status = GetLastError()))
    {
      dwBufferSize = dwBufferUsed;
      rendered_values = std::unique_ptr<EVT_VARIANT, utils::FreeDeleter>((PEVT_VARIANT)(malloc(dwBufferSize)));
      if (rendered_values)
      {
        EvtRender(context, event_ptr_, EvtRenderEventValues, dwBufferSize, rendered_values.get(), &dwBufferUsed, &dwPropertyCount);
      }
    }
    else {
      return;
    }

    if (ERROR_SUCCESS != (status = GetLastError()))
    {
      return;
    }
  }

  event_timestamp_ = static_cast<PEVT_VARIANT>( rendered_values.get())[EvtSystemTimeCreated].FileTimeVal;

  SYSTEMTIME st;
  FILETIME ft;

  ft.dwHighDateTime = (DWORD)((event_timestamp_ >> 32) & 0xFFFFFFFF);
  ft.dwLowDateTime = (DWORD)(event_timestamp_ & 0xFFFFFFFF);

  FileTimeToSystemTime(&ft, &st);
  std::stringstream datestr;

  std::string period = "AM";
  auto hour = st.wHour;
  if (hour >= 12 && hour < 24)
    period = "PM";
  if (hour > 12)
    hour -= 12;
  if (hour == 0)
    hour = 12;
  datestr << st.wMonth << "/" << st.wDay << "/" << st.wYear << " " << std::setfill('0') << std::setw(2) << hour << ":" << std::setfill('0') << std::setw(2) << st.wMinute << ":" << std::setfill('0') << std::setw(2) << st.wSecond << " " << period;
  event_timestamp_str_ = datestr.str();
  auto level = static_cast<PEVT_VARIANT>(rendered_values.get())[EvtSystemLevel];
  auto keyword = static_cast<PEVT_VARIANT>(rendered_values.get())[EvtSystemKeywords];
  if (level.Type == EvtVarTypeByte) {
    switch (level.ByteVal)
    {
      case WINEVENT_LEVEL_CRITICAL:
      case WINEVENT_LEVEL_ERROR:
        event_type_ = "Error";
        event_type_index_ = 1;
        break;
      case WINEVENT_LEVEL_WARNING:
        event_type_ = "Warning";
        event_type_index_ = 2;
        break;
      case WINEVENT_LEVEL_INFO:
      case WINEVENT_LEVEL_VERBOSE:
        event_type_ = "Information";
        event_type_index_ = 4;
        break;
      default:
        event_type_index_ = 0;
    };

  }
  else {
    event_type_ = "N/A";
  }

  if (keyword.UInt64Val & WINEVENT_KEYWORD_AUDIT_SUCCESS) {
    event_type_ = "Success Audit";
    event_type_index_ = 8;
  } else if (keyword.UInt64Val & EVENTLOG_AUDIT_FAILURE) {
    event_type_ = "Failure Audit";
    event_type_index_ = 16;
  }
}

std::string WindowsEventLogMetadataImpl::getEventData(EVT_FORMAT_MESSAGE_FLAGS flags) const {
  LPWSTR string_buffer = NULL;
  DWORD string_buffer_size = 0;
  DWORD string_buffer_used = 0;
  DWORD result = 0;

  std::string event_data;

  if (metadata_ptr_ == NULL || event_ptr_ == NULL) {
    return event_data;
  }

  if (!EvtFormatMessage(metadata_ptr_, event_ptr_, 0, 0, NULL, flags, string_buffer_size, string_buffer, &string_buffer_used)) {
    result = GetLastError();
    if (ERROR_INSUFFICIENT_BUFFER == result) {
      string_buffer_size = string_buffer_used;

      string_buffer = (LPWSTR) malloc(string_buffer_size * sizeof(WCHAR));

      if (string_buffer) {

        if ((EvtFormatMessageKeyword == flags))
          string_buffer[string_buffer_size - 1] = L'\0';

        EvtFormatMessage(metadata_ptr_, event_ptr_, 0, 0, NULL, flags, string_buffer_size, string_buffer, &string_buffer_used);
        if ((EvtFormatMessageKeyword == flags))
          string_buffer[string_buffer_used - 1] = L'\0';
        std::wstring str(string_buffer);
        event_data = std::string(str.begin(), str.end());
        free(string_buffer);
      }
    }
  }
  return event_data;
}

std::string WindowsEventLogHandler::getEventMessage(EVT_HANDLE eventHandle) const
{
  std::string returnValue;
  std::unique_ptr<WCHAR, utils::FreeDeleter> pBuffer;
  DWORD dwBufferSize = 0;
  DWORD dwBufferUsed = 0;
  DWORD status = 0;

  EvtFormatMessage(metadata_provider_, eventHandle, 0, 0, NULL, EvtFormatMessageEvent, dwBufferSize, pBuffer.get(), &dwBufferUsed);
  if (dwBufferUsed == 0) {
    return returnValue;
  }

  //  we need to get the size of the buffer
  status = GetLastError();
  if (ERROR_INSUFFICIENT_BUFFER == status) {
    dwBufferSize = dwBufferUsed;

    /* All C++ examples use malloc and even HeapAlloc in some cases. To avoid any problems ( with EvtFormatMessage calling
      free for example ) we will continue to use malloc and use a custom deleter with unique_ptr.
    '*/
    pBuffer = std::unique_ptr<WCHAR, utils::FreeDeleter>((LPWSTR)malloc(dwBufferSize * sizeof(WCHAR)));
    if (!pBuffer) {
      return returnValue;
    }

    EvtFormatMessage(metadata_provider_, eventHandle, 0, 0, NULL, EvtFormatMessageEvent, dwBufferSize, pBuffer.get(), &dwBufferUsed);
  }

  if (ERROR_EVT_MESSAGE_NOT_FOUND == status || ERROR_EVT_MESSAGE_ID_NOT_FOUND == status) {
    return returnValue;
  }

  // convert wstring to std::string
  return to_string(pBuffer.get());
}

void WindowsEventLogHeader::setDelimiter(const std::string &delim) {
  delimiter_ = delim;
}

std::string WindowsEventLogHeader::createDefaultDelimiter(size_t max, size_t length) const {
  if (max > length) {
    return ":" + std::string(max - length, ' ');
  }
  else {
    return ": ";
  }
}

EVT_HANDLE WindowsEventLogHandler::getMetadata() const {
  return metadata_provider_;
}

} /* namespace wel */
} /* namespace minifi */
} /* namespace nifi */
} /* namespace apache */
} /* namespace org */

