# SPDX-License-Identifier: Apache-2.0
# Copyright 2019 The Meson development team

from __future__ import annotations

import os
import argparse
import subprocess
from pathlib import Path
import typing as T

from ..mesonlib import Popen_safe, split_args, determine_worker_count
from .. import mlog

class ExternalProject:
    def __init__(self, options: argparse.Namespace):
        self.name = options.name
        self.src_dir = options.srcdir
        self.build_dir = options.builddir
        self.install_dir = options.installdir
        self.log_dir = options.logdir
        self.verbose = options.verbose
        self.stampfile = options.stampfile
        self.depfile = options.depfile
        self.make = split_args(options.make)

    def write_depfile(self) -> None:
        with open(self.depfile, 'w', encoding='utf-8') as f:
            f.write(f'{self.stampfile}: \\\n')
            for dirpath, dirnames, filenames in os.walk(self.src_dir):
                dirnames[:] = [d for d in dirnames if not d.startswith('.')]
                for fname in filenames:
                    if fname.startswith('.'):
                        continue
                    path = Path(dirpath, fname)
                    f.write('  {} \\\n'.format(path.as_posix().replace(' ', '\\ ')))

    def write_stampfile(self) -> None:
        with open(self.stampfile, 'w', encoding='utf-8'):
            pass

    def supports_jobs_flag(self) -> bool:
        p, o, e = Popen_safe(self.make + ['--version'])
        if p.returncode == 0 and ('GNU Make' in o or 'waf' in o):
            return True
        return False

    def build(self) -> int:
        make_cmd = self.make.copy()
        if self.supports_jobs_flag():
            make_cmd.append(f'-j{determine_worker_count()}')
        rc = self._run('build', make_cmd)
        if rc != 0:
            return rc

        install_cmd = self.make.copy()
        install_env = {}
        install_env['DESTDIR'] = self.install_dir
        install_cmd.append('install')
        rc = self._run('install', install_cmd, install_env)
        if rc != 0:
            return rc

        self.write_depfile()
        self.write_stampfile()

        return 0

    def _run(self, step: str, command: T.List[str], env: T.Optional[T.Dict[str, str]] = None) -> int:
        m = 'Running command ' + str(command) + ' in directory ' + str(self.build_dir) + '\n'
        logfile = Path(self.log_dir, f'{self.name}-{step}.log')
        output = None
        if not self.verbose:
            output = open(logfile, 'w', encoding='utf-8')
            output.write(m + '\n')
            output.flush()
        else:
            print(m)
        run_env = os.environ.copy()
        if env:
            run_env.update(env)
        p, o, e = Popen_safe(command, stderr=subprocess.STDOUT, stdout=output,
                             cwd=self.build_dir,
                             env=run_env)
        if p.returncode != 0:
            m = f'{step} step returned error code {p.returncode}.'
            if not self.verbose:
                m += '\nSee logs: ' + str(logfile)
            print(m)
            contents = mlog.ci_fold_file(logfile, f'CI platform detected, click here for {os.path.basename(logfile)} contents.')
            if contents:
                print(contents)
        return p.returncode

def run(args: T.List[str]) -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument('--name')
    parser.add_argument('--srcdir')
    parser.add_argument('--builddir')
    parser.add_argument('--installdir')
    parser.add_argument('--logdir')
    parser.add_argument('--make')
    parser.add_argument('--verbose', action='store_true')
    parser.add_argument('stampfile')
    parser.add_argument('depfile')

    options = parser.parse_args(args)
    ep = ExternalProject(options)
    return ep.build()
