# This source file is part of the Swift.org open source project
#
# Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
# Licensed under Apache License v2.0 with Runtime Library Exception
#
# See http://swift.org/LICENSE.txt for license information
# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors

"""
Bindings for the llbuild C API.

This is incomplete, and has several serious issues.
"""

import cffi
import os
import re

###
# TODO
#
# 1. Deal with leaks of Task and Rule objects, because of the handle cycle. We
#    need the C-API to allow us to do cleanup on the Task and Delegate user
#    contex pointers.

###

class AbstractError(Exception):
    pass

###

ffi = cffi.FFI()

# Load the defs by reading the llbuild header directly.
data = open(os.path.join(
    os.path.dirname(__file__),
    "../../products/libllbuild/public-api/llbuild/llbuild.h")).read()
# Strip out the directives.
data = re.sub("^#.*", "", data, 0, re.MULTILINE)
data = re.sub("LLBUILD_EXPORT", "", data, 0, re.MULTILINE)
ffi.cdef(data)

# Load the dylib.
#
# FIXME: Need a way to find this.
libllbuild = ffi.dlopen(os.path.join(
    os.path.dirname(__file__),
    "../../build/lib/libllbuild.dylib"))

@ffi.callback("void(void*, void*, llb_task_t*)")
def _task_start(context, engine_context, _task):
    task = ffi.from_handle(context)
    engine = ffi.from_handle(engine_context)

    task.start(engine)

@ffi.callback(
    "void(void*, void*, llb_task_t*, uintptr_t, llb_data_t*)")
def _task_provide_value(context, engine_context, task, input_id, value):
    task = ffi.from_handle(context)
    engine = ffi.from_handle(engine_context)

    task.provide_value(engine, input_id,
                       str(ffi.buffer(value.data, value.length)))
    
@ffi.callback("void(void*, void*, llb_task_t*)")
def _task_inputs_available(context, engine_context, llb_task):
    task = ffi.from_handle(context)
    engine = ffi.from_handle(engine_context)

    # Notify the task.
    task.inputs_available(engine)

@ffi.callback("llb_task_t*(void*, void*)")
def _rule_create_task(context, engine_context):
    rule = ffi.from_handle(context)
    engine = ffi.from_handle(engine_context)

    # Create the task.
    task = rule.create_task()
    assert isinstance(task, Task)

    # FIXME: Should we pass the context pointer separately from the delegate
    # structure, so it can be reused?
    delegate = ffi.new("llb_task_delegate_t*")
    delegate.context = task._handle
    delegate.start = _task_start
    delegate.provide_value = _task_provide_value
    delegate.inputs_available = _task_inputs_available

    task._task = libllbuild.llb_task_create(delegate[0])
    return libllbuild.llb_buildengine_register_task(engine._engine, task._task)

@ffi.callback("bool(void*, void*, llb_rule_t*, llb_data_t*)")
def _rule_is_result_valid(context, engine_context, rule, value):
    rule = ffi.from_handle(context)
    engine = ffi.from_handle(engine_context)

    return rule.is_result_valid(
        engine, str(ffi.buffer(value.data, value.length)))

@ffi.callback("void(void*, void*, llb_rule_status_kind_t)")
def _rule_update_status(context, engine_context, kind):
    rule = ffi.from_handle(context)
    engine = ffi.from_handle(engine_context)

    rule.update_status(engine, kind)

@ffi.callback("void(void*, llb_data_t*, llb_rule_t*)")
def _buildengine_lookup_rule(context, key, rule_out):
    engine = ffi.from_handle(context)
    rule = engine.delegate.lookup_rule(str(ffi.buffer(key.data, key.length)))

    # Initialize the rule result from the given object.
    assert isinstance(rule, Rule)

    # FIXME: What is to prevent the rule from being deallocated after this
    # point? We only are passing back a handle.
    rule_out.context = rule._handle
    rule_out.create_task = _rule_create_task
    rule_out.is_result_valid = _rule_is_result_valid
    rule_out.update_status = _rule_update_status
    
class _Data(object):
    """Wrapper for a key and its data."""
    def __init__(self, name):
        name = str(name)
        self.key = ffi.new("llb_data_t*")
        self.key.length = length = len(name)
        # Store in a local to keep alive.
        self._datap = ffi.new("char[]", length)
        self.key.data = self._datap
        # Copy in the data.
        ffi.buffer(self.key.data, length)[:] = name

class _HandledObject(object):
    _all_handles = []
    _handle_cache = None
    @property
    def _handle(self):
        # FIXME: This creates a cycle.
        if self._handle_cache is None:
            self._handle_cache = handle = ffi.new_handle(self)
            # FIXME: This leaks everything, but we are currently dropping a
            # handle somewhere.
            self._all_handles.append(handle)
        return self._handle_cache
            
###

def get_full_version():
    return ffi.string(libllbuild.llb_get_full_version_string())
        
class Task(_HandledObject):
    _task = None

    def start(self, engine):
        pass

    def provide_value(self, engine, input_id, value):
        # We consider it a runtime error for a task to receive a value if it
        # didn't override this callback.
        raise RuntimeError()

    def inputs_available(self, engine):
        raise AbstractError()

class Rule(_HandledObject):
    def create_task(self):
        raise AbstractError()

    def is_result_valid(self, engine, result):
        return True

    def update_status(self, engine, kind):
        pass

class BuildEngineDelegate(object):
    pass

class BuildEngine(_HandledObject):
    def __init__(self, delegate):
        # Store our delegate.
        self.delegate = delegate

        # Create the engine delegate.
        self._llb_delegate = ffi.new("llb_buildengine_delegate_t*")
        self._llb_delegate.context = self._handle
        self._llb_delegate.lookup_rule = _buildengine_lookup_rule

        # Create the underlying engine.
        self._engine = libllbuild.llb_buildengine_create(self._llb_delegate[0])

    ###
    # Client API

    def build(self, key):
        """
        build(key) -> value

        Compute the result for the given key.
        """

        # Create a data version of the key.
        key_data = _Data(key)

        # Request the build.
        result = ffi.new("llb_data_t*")
        libllbuild.llb_buildengine_build(self._engine, key_data.key, result)

        # Copy out the result.
        return str(ffi.buffer(result.data, result.length))

    def attach_db(self, path, schema_version=1):
        """
        attach_db(path, schema_version=1) -> None

        Attach a database to store the build results.
        """

        error = ffi.new("char *")
        path = _Data(path)
        if not libllbuild.llb_buildengine_attach_db(
                self._engine, path.key, schema_version, error):
            raise IOError("unable to attach database; %r" % (
                ffi.string(error),))
        
    def close(self):
        """
        close() -- Close the engine connection.
        """
        self._handle_cache = None
        libllbuild.llb_buildengine_destroy(self._engine)
        self._engine = None

    ###
    # Task API

    def task_needs_input(self, task, key, input_id=0):
        """\
task_needs_input(task, key, input_id)

Specify the given \arg Task depends upon the result of computing \arg key.

The result, when available, will be provided to the task via \see
provide_value(), supplying the provided \arg input_id to allow the
task to identify the particular input.

NOTE: It is an unchecked error for a task to request the same input value
multiple times.

\param input_id An arbitrary value that may be provided by the client to
use in efficiently associating this input. The range of this parameter is
intentionally chosen to allow a pointer to be provided."""
        key = _Data(key)
        libllbuild.llb_buildengine_task_needs_input(
            self._engine, task._task, key.key, input_id)

    def task_must_follow(self, task, key):
        """\
task_must_follow(task, key)

Specify that the given \arg task must be built subsequent to the
computation of \arg key.

The value of the computation of \arg key is not available to the task, and the
only guarantee the engine provides is that if \arg key is computed during a
build, then \arg Task will not be computed until after it."""
        key = _Data(key)
        libllbuild.llb_buildengine_task_must_follow(
            self._engine, task._task, key.key)

    def task_discovered_dependency(self, task, key):
        """\
task_discovered_dependency(task, key)

Inform the engine of an input dependency that was discovered by the task
during its execution, a la compiler generated dependency files.

This call may only be made after a task has received all of its inputs;
inputs discovered prior to that point should simply be requested as normal
input dependencies.

Such a dependency is not used to provide additional input to the task,
rather it is a way for the task to report an additional input which should
be considered the next time the rule is evaluated. The expected use case
for a discovered dependency is is when a processing task cannot predict
all of its inputs prior to being run, but can presume that any unknown
inputs already exist. In such cases, the task can go ahead and run and can
report the all of the discovered inputs as it executes. Once the task is
complete, these inputs will be recorded as being dependencies of the task
so that it will be recomputed when any of the inputs change.

It is legal to call this method from any thread, but the caller is
responsible for ensuring that it is never called concurrently for the same
task."""
        key = _Data(key)
        libllbuild.llb_buildengine_task_must_follow(
            self._engine, task._task, key.key)

    def task_is_complete(self, task, value, force_change=False):
        """\
task_is_complete(task, value, force_change=False)

Called by a task to indicate it has completed and to provide its value.

It is legal to call this method from any thread.

\param value The new value for the task's rule.

\param force_change If true, treat the value as changed and trigger
dependents to rebuild, even if the value itself is not different from the
prior result."""
        # Complete the result.
        value = _Data(value)
        libllbuild.llb_buildengine_task_is_complete(
            self._engine, task._task, value.key, force_change)

__all__ = ['get_full_version', 'BuildEngine', 'Rule', 'Task']
