/*
 * 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 "UtilAll.h"

#include "LoggerImpl.h"
#include "zlib.h"
#include <cstring>

#if defined(__APPLE__)
#include <net/if_dl.h>
#define AF_FAMILY AF_LINK
#elif defined(__linux__)
#include <arpa/inet.h>
#include <net/ethernet.h>
#include <netpacket/packet.h>
#define AF_FAMILY AF_PACKET
#elif defined(_WIN32)
#include <Windows.h>
#include <iphlpapi.h>
#pragma comment(lib, "iphlpapi.lib")
#endif

#ifndef _WIN32
#include <ifaddrs.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#endif

#include "asio.hpp"

ROCKETMQ_NAMESPACE_BEGIN

std::string UtilAll::hostname() {
  return asio::ip::host_name();
}

bool UtilAll::macAddress(std::vector<unsigned char>& mac) {
  static std::vector<unsigned char> cache;
  static bool mac_cached = false;

  if (mac_cached) {
    mac = cache;
    return true;
  }

#ifndef _WIN32
  struct ifaddrs *head = nullptr, *node;
  if (getifaddrs(&head)) {
    return false;
  }

  for (node = head; node; node = node->ifa_next) {
    if (node->ifa_addr->sa_family == AF_FAMILY) {
#if defined(__APPLE__)
      auto* ptr = reinterpret_cast<unsigned char*>(LLADDR(reinterpret_cast<struct sockaddr_dl*>(node->ifa_addr)));
#elif defined(__linux__)
      auto* ptr = reinterpret_cast<unsigned char*>(reinterpret_cast<struct sockaddr_ll*>(node->ifa_addr)->sll_addr);
#endif
      bool all_zero = true;
      for (int i = 0; i < 6; i++) {
        if (*(ptr + i) != 0) {
          all_zero = false;
          break;
        }
      }
      if (all_zero) {
        SPDLOG_TRACE("Skip MAC address of network interface {}", node->ifa_name);
        continue;
      }
      SPDLOG_DEBUG("Use MAC address of network interface {}", node->ifa_name);
      // MAC address has 48 bits
      cache.resize(6);
      memcpy(cache.data(), ptr, 6);
      mac_cached = true;
      mac = cache;
      break;
    }
  }
  freeifaddrs(head);
  return true;
#else
  PIP_ADAPTER_INFO adaptor_info;
  DWORD buf_len = sizeof(IP_ADAPTER_INFO);
  char mac_address[18];
  adaptor_info = (IP_ADAPTER_INFO*)malloc(buf_len);
  if (!adaptor_info) {
    // TODO: running out of memroy
  }

  if (GetAdaptersInfo(adaptor_info, &buf_len) == NO_ERROR) {
    PIP_ADAPTER_INFO item = adaptor_info;
    do {
      bool all_zero = true;
      for (auto& b : item->Address) {
        if (b != 0) {
          all_zero = false;
          break;
        }
      }
      if (!all_zero) {
        cache.resize(6);
        memcpy(cache.data(), item->Address, 6);
        mac_cached = true;
        mac = cache;
        break;
      }
      item = item->Next;
    } while (item);
  } else {
    free(adaptor_info);
  }
#endif
}

bool UtilAll::compress(const std::string& src, std::string& dst) {
  z_stream stream;
  stream.zalloc = Z_NULL;
  stream.zfree = Z_NULL;
  stream.opaque = Z_NULL;
  stream.next_in = reinterpret_cast<unsigned char*>(const_cast<char*>(src.c_str()));
  stream.avail_in = src.length();

  deflateInit(&stream, Z_DEFAULT_COMPRESSION);
  uint32_t bound = deflateBound(&stream, src.length());
  std::vector<unsigned char> buffer(bound);
  stream.next_out = buffer.data();
  stream.avail_out = bound;

  int status = deflate(&stream, Z_FINISH);

  // zlib is unexpected wrong.
  if (Z_STREAM_END != status) {
    deflateEnd(&stream);
    return false;
  }

  dst.reserve(stream.total_out);
  assert(stream.total_out == bound - stream.avail_out);
  std::copy(buffer.data(), buffer.data() + stream.total_out, std::back_inserter(dst));
  deflateEnd(&stream);
  return true;
}

bool UtilAll::uncompress(const std::string& src, std::string& dst) {
  int status;
  uint32_t buffer_length = 4096;
  std::vector<unsigned char> buffer(buffer_length);
  z_stream stream;

  // Use default malloc / free allocator.
  stream.zalloc = Z_NULL;
  stream.zfree = Z_NULL;
  stream.opaque = Z_NULL;
  stream.next_in = reinterpret_cast<unsigned char*>(const_cast<char*>(src.c_str()));
  stream.avail_in = src.length();

  inflateInit(&stream);
  stream.next_out = buffer.data();
  stream.avail_out = buffer_length;

  while (true) {
    status = inflate(&stream, Z_SYNC_FLUSH);

    if (Z_STREAM_ERROR == status) {
      return false;
    }
    std::copy(buffer.data(), buffer.data() + buffer_length - stream.avail_out, std::back_inserter(dst));
    stream.avail_out = buffer_length;
    stream.next_out = buffer.data();

    // inflation completed OK
    if (Z_STREAM_END == status) {
      inflateEnd(&stream);
      return true;
    }

    // inflation made some progress
    if (Z_OK == status) {
      continue;
    }

    // Something is wrong
    inflateEnd(&stream);
    return false;
  }
}

ROCKETMQ_NAMESPACE_END