"""
When using this tool, the wscript should look like:

    def options(opt):
        opt.load('openssl')

    def configure(conf):
        conf.load('compiler_cxx openssl')
        conf.check_openssl()

    def build(bld):
        bld(source='main.cpp', target='app', use='OPENSSL')
"""

import re
from waflib import Utils
from waflib.Configure import conf

OPENSSL_DIR = ['/usr', '/usr/local', '/opt/local', '/sw']
OPENSSL_DIR_MACOS = ['/usr/local',
                     '/opt/homebrew/opt/openssl', # Homebrew on arm64
                     '/usr/local/opt/openssl',    # Homebrew on x86_64
                     '/opt/local']                # MacPorts

def options(opt):
    opt.add_option('--with-openssl', type='string', default=None, dest='openssl_dir',
                   help='directory where OpenSSL is installed, e.g., /usr/local')

@conf
def __openssl_get_version_file(self, dir):
    try:
        return self.root.find_dir(dir).find_node('include/openssl/opensslv.h')
    except:
        return None

@conf
def __openssl_find_root_and_version_file(self, root):
    if root:
        file = self.__openssl_get_version_file(root)
        if not file:
            self.fatal(f'OpenSSL not found in {root}')
        return (root, file)

    openssl_dirs = OPENSSL_DIR
    if Utils.unversioned_sys_platform() == 'darwin':
        openssl_dirs = OPENSSL_DIR_MACOS

    for dir in openssl_dirs:
        file = self.__openssl_get_version_file(dir)
        if file:
            return (dir, file)

    self.fatal('OpenSSL not found, please provide a --with-openssl=PATH argument (see --help)')

@conf
def __openssl_check_version(self, version_file, atleast_version):
    min_version = tuple(int(i) for i in atleast_version.split('.'))
    txt = version_file.read()

    # OpenSSL 3.0.0 and later
    ver_tuple = (re.search(r'^#\s*define\s+OPENSSL_VERSION_MAJOR\s+(\d+)', txt, re.MULTILINE),
                 re.search(r'^#\s*define\s+OPENSSL_VERSION_MINOR\s+(\d+)', txt, re.MULTILINE),
                 re.search(r'^#\s*define\s+OPENSSL_VERSION_PATCH\s+(\d+)', txt, re.MULTILINE))
    ver_string = re.search(r'^#\s*define\s+OPENSSL_FULL_VERSION_STR\s+"(.+)"', txt, re.MULTILINE)
    if all(ver_tuple):
        version = tuple(int(i[1]) for i in ver_tuple)
        ver_string = ver_string[1] if ver_string else '.'.join(version)
        return (version >= min_version, ver_string)

    # OpenSSL 1.1.1 and earlier
    ver_number = re.search(r'^#\s*define\s+OPENSSL_VERSION_NUMBER\s+(.+)L', txt, re.MULTILINE)
    ver_string = re.search(r'^#\s*define\s+OPENSSL_VERSION_TEXT\s+"(.+)"', txt, re.MULTILINE)
    if ver_number and ver_string:
        version = int(ver_number[1], 16)
        min_version = (min_version[0] << 28) | (min_version[1] << 20) | (min_version[2] << 12) | 0xf
        return (version >= min_version, ver_string[1])

    self.fatal(f'Cannot extract version information from {version_file}')

@conf
def check_openssl(self, *k, **kw):
    self.start_msg('Checking for OpenSSL version')

    path = k and k[0] or kw.get('path', self.options.openssl_dir)
    root, version_file = self.__openssl_find_root_and_version_file(path)
    atleast_version = kw.get('atleast_version', 0)
    ok, version_str = self.__openssl_check_version(version_file, atleast_version)

    self.end_msg(version_str)
    if not ok:
        self.fatal(f'The version of OpenSSL is too old; {atleast_version} or later is required.\n'
                   'Please upgrade your distribution or manually install a newer version of OpenSSL.')

    if 'msg' not in kw:
        kw['msg'] = 'Checking if OpenSSL library works'
    if 'lib' not in kw:
        kw['lib'] = ['ssl', 'crypto']
    if 'uselib_store' not in kw:
        kw['uselib_store'] = 'OPENSSL'
    if 'define_name' not in kw:
        kw['define_name'] = f"HAVE_{kw['uselib_store']}"
    kw['includes'] = f'{root}/include'
    kw['libpath'] = f'{root}/lib'

    self.check_cxx(**kw)
