#!/usr/bin/env python
#
# 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.
"""
Simple script which checks that the build system has the main
dependencies necessary for building thirdparty/.

This is not meant to be exhaustive. For example, it doesn't check specific
version numbers of software. Nor is it meant to be a replacement for
more complicated config tests using something like autoconf or cmake.
But, it's simple enough that it runs with no dependencies and tells
users if they're missing anything obvious.
"""

import os
import platform
import sys
import subprocess

DEV_NULL = open("/dev/null", "wb")
CC = os.environ.get("CC", "cc")
CXX = os.environ.get("CXX", "c++")

REQUIRED_TOOLS = [
  "autoconf",
  "automake",
  "curl",
  "flex",
  "git",
  "make",
  "patch",
  "perl",
  "pkg-config",
  "rsync",
  "unzip",
  "xxd"]

if platform.system() == "Linux":
  # Modern Linux distros split libtool functionality into two packages:
  # libtool-bin (containing 'libtool') and libtool (containing 'libtoolize').
  # Only the latter is needed for a working autoconf.
  REQUIRED_TOOLS.append("libtoolize")
else:
  REQUIRED_TOOLS.append("libtool")

def log_failure_and_exit(error_msg, exc=None):
  print("*** " + error_msg)
  if exc:
    print(exc.message)
    print("")
  print("Please refer to docs/installation.adoc for complete installation ")
  print("instructions for your platform.")
  sys.exit(1)


def try_do(status_msg, error_msg, func):
  print(status_msg + " ...")
  try:
    func()
  except Exception as e:
    log_failure_and_exit(error_msg, e)


def compile(script, flags=None):
  if flags is None:
    flags = []

  p = subprocess.Popen([CXX, '-o', '/dev/null', '-c', '-x', 'c++', '-'] + flags,
      stderr=subprocess.PIPE,
      stdout=subprocess.PIPE,
      stdin=subprocess.PIPE,
      universal_newlines=True)

  stdout, stderr = p.communicate(input=script)
  if p.returncode != 0:
    raise Exception("Compilation failed: " + stderr)


def check_tools():
  """ Check that basic build tools are installed. """
  missing = []
  for tool in REQUIRED_TOOLS:
    print("Checking for " + tool)
    if subprocess.call(["which", tool], stdout=DEV_NULL, stderr=DEV_NULL) != 0:
      missing.append(tool)
  if missing:
    log_failure_and_exit("Missing required tools:\n" +
      "\n".join("  " + tool for tool in missing))


def check_cxx17():
  # Check that the compiler is new enough.
  try_do(
    "Checking for C++17 compiler support",
    ("Unable to compile a simple c++17 program. " +
     "Please use g++ 7.0 or higher (or CLANG 6.0 or higher). On CentOS 7 or "
     "RHEL 7 you must use the devtoolset. See docs/installation.adoc " +
     "for more info."),
    lambda: compile("""
      #include <optional>
      int f() {
        std::optional<int> oi = 0;
        return *oi;
      }""",
      flags=['--std=c++17']))


def check_sasl():
  try_do(
    "Checking for cyrus-sasl headers",
    ("Unable to compile a simple program that uses sasl. " +
     "Please check that cyrus-sasl-devel (RPM) or libsasl2-dev (deb) " +
     "dependencies are installed."),
    lambda: compile("""
      #include <sasl/sasl.h>
      """,
      flags=["-E"]))

def check_openssl():
  cflags = ["-E"]
  proc = subprocess.Popen(["pkg-config", "--cflags", "openssl"], stdout=subprocess.PIPE)
  openssl_include = proc.communicate()[0].decode("utf-8").rstrip()
  if openssl_include != "":
    cflags.append(openssl_include)
  else:
    homebrew_openssl_dir="/usr/local/opt/openssl/include"
    if os.path.isdir(homebrew_openssl_dir):
      cflags.append("-I" + homebrew_openssl_dir)
  try_do(
    "Checking for openssl headers",
    ("Unable to compile a simple program that uses openssl. " +
     "Please check that openssl-devel (RPM) or libssl-dev (deb) " +
     "dependencies are installed."),
    lambda: compile("""
      #include <openssl/ssl.h>
      """,
      flags=cflags))

def main():
  print("Running pre-flight checks")
  print("-------------------------")
  print("Using C compiler: " + CC)
  print("Using C++ compiler: " + CXX)
  print("")
  print("  (Set $CC and $CXX to change compiler)")
  print("-------------------------")
  check_tools()
  check_cxx17()
  check_sasl()
  check_openssl()
  print("-------------")
  print("Pre-flight checks succeeded.")
  return 0

if __name__ == "__main__":
  sys.exit(main())
