/*
 * 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