# Copyright 2016 gRPC authors.
#
# Licensed 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.

from distutils import errors
import os
import os.path
import shutil
import sys
import tempfile

import commands

C_PYTHON_DEV = """
#include <Python.h>
int main(int argc, char **argv) { return 0; }
"""
C_PYTHON_DEV_ERROR_MESSAGE = """
Could not find <Python.h>. This could mean the following:
  * You're on Ubuntu and haven't run `apt-get install <PY_REPR>-dev`.
  * You're on RHEL/Fedora and haven't run `yum install <PY_REPR>-devel` or
    `dnf install <PY_REPR>-devel` (make sure you also have redhat-rpm-config
    installed)
  * You're on Mac OS X and the usual Python framework was somehow corrupted
    (check your environment variables or try re-installing?)
  * You're on Windows and your Python installation was somehow corrupted
    (check your environment variables or try re-installing?)
"""
if sys.version_info[0] == 2:
    PYTHON_REPRESENTATION = "python"
elif sys.version_info[0] == 3:
    PYTHON_REPRESENTATION = "python3"
else:
    raise NotImplementedError("Unsupported Python version: %s" % sys.version)

C_CHECKS = {
    C_PYTHON_DEV: C_PYTHON_DEV_ERROR_MESSAGE.replace(
        "<PY_REPR>", PYTHON_REPRESENTATION
    ),
}


def _compile(compiler, source_string):
    tempdir = tempfile.mkdtemp()
    cpath = os.path.join(tempdir, "a.c")
    with open(cpath, "w") as cfile:
        cfile.write(source_string)
    try:
        compiler.compile([cpath])
    except errors.CompileError as error:
        return error
    finally:
        shutil.rmtree(tempdir)


def _expect_compile(compiler, source_string, error_message):
    if _compile(compiler, source_string) is not None:
        sys.stderr.write(error_message)
        raise commands.CommandError(
            "Diagnostics found a compilation environment issue:\n{}".format(
                error_message
            )
        )


def diagnose_compile_error(build_ext, error):
    """Attempt to diagnose an error during compilation."""
    for c_check, message in C_CHECKS.items():
        _expect_compile(build_ext.compiler, c_check, message)
    python_sources = [
        source
        for source in build_ext.get_source_files()
        if source.startswith("./src/python") and source.endswith("c")
    ]
    for source in python_sources:
        if not os.path.isfile(source):
            raise commands.CommandError(
                (
                    "Diagnostics found a missing Python extension source"
                    " file:\n{}\n\nThis is usually because the Cython sources"
                    " haven't been transpiled into C yet and you're building"
                    " from source.\nTry setting the environment variable"
                    " `GRPC_PYTHON_BUILD_WITH_CYTHON=1` when invoking"
                    " `setup.py` or when using `pip`, e.g.:\n\npip install"
                    " -rrequirements.txt\nGRPC_PYTHON_BUILD_WITH_CYTHON=1 pip"
                    " install ."
                ).format(source)
            )


def diagnose_attribute_error(build_ext, error):
    if any("_needs_stub" in arg for arg in error.args):
        raise commands.CommandError(
            "We expect a missing `_needs_stub` attribute from older versions of"
            " setuptools. Consider upgrading setuptools."
        )


_ERROR_DIAGNOSES = {
    errors.CompileError: diagnose_compile_error,
    AttributeError: diagnose_attribute_error,
}


def diagnose_build_ext_error(build_ext, error, formatted):
    diagnostic = _ERROR_DIAGNOSES.get(type(error))
    if diagnostic is None:
        raise commands.CommandError(
            "\n\nWe could not diagnose your build failure. If you are unable to"
            " proceed, please file an issue at http://www.github.com/grpc/grpc"
            " with `[Python install]` in the title; please attach the whole log"
            " (including everything that may have appeared above the Python"
            " backtrace).\n\n{}".format(formatted)
        )
    else:
        diagnostic(build_ext, error)
