'''
Scons Builder for nanopb .proto definitions.

This tool will locate the nanopb generator and use it to generate .pb.c and
.pb.h files from the .proto files.

Basic example
-------------
# Build myproto.pb.c and myproto.pb.h from myproto.proto
myproto = env.NanopbProto("myproto")

# Link nanopb core to the program
env.Append(CPPPATH = "$NANOB")
myprog = env.Program(["myprog.c", myproto, "$NANOPB/pb_encode.c", "$NANOPB/pb_decode.c"])

Configuration options
---------------------
Normally, this script is used in the test environment of nanopb and it locates
the nanopb generator by a relative path. If this script is used in another
application, the path to nanopb root directory has to be defined:

env.SetDefault(NANOPB = "path/to/nanopb")

Additionally, the path to protoc and the options to give to protoc can be
defined manually:

env.SetDefault(PROTOC = "path/to/protoc")
env.SetDefault(PROTOCFLAGS = "--plugin=protoc-gen-nanopb=path/to/protoc-gen-nanopb")
'''

import SCons.Action
import SCons.Builder
import SCons.Util
from SCons.Script import Dir, File
import os.path
import platform

try:
    warningbase = SCons.Warnings.SConsWarning
except AttributeError:
    warningbase = SCons.Warnings.Warning

class NanopbWarning(warningbase):
    pass
SCons.Warnings.enableWarningClass(NanopbWarning)

def _detect_nanopb(env):
    '''Find the path to nanopb root directory.'''
    if 'NANOPB' in env:
        # Use nanopb dir given by user
        return env['NANOPB']

    p = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..'))
    if os.path.isdir(p) and os.path.isfile(os.path.join(p, 'pb.h')):
        # Assume we are running under tests/site_scons/site_tools
        return p

    raise SCons.Errors.StopError(NanopbWarning,
        "Could not find the nanopb root directory")

def _detect_python(env):
    '''Find Python executable to use.'''
    if 'PYTHON' in env:
        return env['PYTHON']

    p = env.WhereIs('python3')
    if p:
        return env['ESCAPE'](p)

    p = env.WhereIs('py.exe')
    if p:
        return env['ESCAPE'](p) + " -3"

    return env['ESCAPE'](sys.executable)

def _detect_nanopb_generator(env):
    '''Return command for running nanopb_generator.py'''
    generator_cmd = os.path.join(env['NANOPB'], 'generator-bin', 'nanopb_generator' + env['PROGSUFFIX'])
    if os.path.exists(generator_cmd):
        # Binary package
        return env['ESCAPE'](generator_cmd)
    else:
        # Source package
        return env['PYTHON'] + " " + env['ESCAPE'](os.path.join(env['NANOPB'], 'generator', 'nanopb_generator.py'))

def _detect_protoc(env):
    '''Find the path to the protoc compiler.'''
    if 'PROTOC' in env:
        # Use protoc defined by user
        return env['PROTOC']

    n = _detect_nanopb(env)
    p1 = os.path.join(n, 'generator-bin', 'protoc' + env['PROGSUFFIX'])
    if os.path.exists(p1):
        # Use protoc bundled with binary package
        return env['ESCAPE'](p1)

    p = os.path.join(n, 'generator', 'protoc')
    if os.path.exists(p):
        # Use the grcpio-tools protoc wrapper
        if env['PLATFORM'] == 'win32':
            return env['ESCAPE'](p + '.bat')
        else:
            return env['ESCAPE'](p)

    p = env.WhereIs('protoc')
    if p:
        # Use protoc from path
        return env['ESCAPE'](p)

    raise SCons.Errors.StopError(NanopbWarning,
        "Could not find the protoc compiler")

def _detect_protocflags(env):
    '''Find the options to use for protoc.'''
    if 'PROTOCFLAGS' in env:
        return env['PROTOCFLAGS']

    p = _detect_protoc(env)
    n = _detect_nanopb(env)
    p1 = os.path.join(n, 'generator', 'protoc' + env['PROGSUFFIX'])
    p2 = os.path.join(n, 'generator-bin', 'protoc' + env['PROGSUFFIX'])
    if p in [env['ESCAPE'](p1), env['ESCAPE'](p2)]:
        # Using the bundled protoc, no options needed
        return ''

    e = env['ESCAPE']
    if env['PLATFORM'] == 'win32':
        return e('--plugin=protoc-gen-nanopb=' + os.path.join(n, 'generator', 'protoc-gen-nanopb.bat'))
    else:
        return e('--plugin=protoc-gen-nanopb=' + os.path.join(n, 'generator', 'protoc-gen-nanopb'))

def _nanopb_proto_actions(source, target, env, for_signature):
    esc = env['ESCAPE']

    # Make protoc build inside the SConscript directory
    prefix = os.path.dirname(str(source[-1]))
    srcfile = esc(os.path.relpath(str(source[0]), prefix))
    include_dirs = '-I.'
    for d in env['PROTOCPATH']:
        d = env.GetBuildPath(d)
        if not os.path.isabs(d): d = os.path.relpath(d, prefix)
        include_dirs += ' -I' + esc(d)

    # when generating .pb.cpp sources, instead of pb.h generate .pb.hpp headers
    source_extension = os.path.splitext(str(target[0]))[1]
    header_extension = '.h' + source_extension[2:]
    nanopb_flags = env['NANOPBFLAGS']
    if nanopb_flags:
      nanopb_flags = '--source-extension=%s,--header-extension=%s,%s:.' % (source_extension, header_extension, nanopb_flags)
    else:
      nanopb_flags = '--source-extension=%s,--header-extension=%s:.' % (source_extension, header_extension)

    return SCons.Action.CommandAction('$PROTOC $PROTOCFLAGS %s --nanopb_out=%s %s' % (include_dirs, nanopb_flags, srcfile),
                                      chdir = prefix)

def _nanopb_proto_emitter(target, source, env):
    basename = os.path.splitext(str(source[0]))[0]
    source_extension = os.path.splitext(str(target[0]))[1]
    header_extension = '.h' + source_extension[2:]
    target.append(basename + '.pb' + header_extension)

    # This is a bit of a hack. protoc include paths work the sanest
    # when the working directory is the same as the source root directory.
    # To get that directory in _nanopb_proto_actions, we add SConscript to
    # the list of source files.
    source.append(File("SConscript"))

    if os.path.exists(basename + '.options'):
        source.append(basename + '.options')

    return target, source

_nanopb_proto_builder = SCons.Builder.Builder(
    generator = _nanopb_proto_actions,
    suffix = '.pb.c',
    src_suffix = '.proto',
    emitter = _nanopb_proto_emitter)

_nanopb_proto_cpp_builder = SCons.Builder.Builder(
    generator = _nanopb_proto_actions,
    suffix = '.pb.cpp',
    src_suffix = '.proto',
    emitter = _nanopb_proto_emitter)

def generate(env):
    '''Add Builder for nanopb protos.'''

    env['NANOPB'] = _detect_nanopb(env)
    env['PROTOC'] = _detect_protoc(env)
    env['PROTOCFLAGS'] = _detect_protocflags(env)
    env['PYTHON'] = _detect_python(env)
    env['NANOPB_GENERATOR'] = _detect_nanopb_generator(env)
    env.SetDefault(NANOPBFLAGS = '')

    env.SetDefault(PROTOCPATH = [".", os.path.join(env['NANOPB'], 'generator', 'proto')])

    env.SetDefault(NANOPB_PROTO_CMD = '$PROTOC $PROTOCFLAGS --nanopb_out=$NANOPBFLAGS:. $SOURCES')
    env['BUILDERS']['NanopbProto'] = _nanopb_proto_builder
    env['BUILDERS']['NanopbProtoCpp'] = _nanopb_proto_cpp_builder

def exists(env):
    return _detect_protoc(env) and _detect_protoc_opts(env)

