#!/usr/bin/env python3

# Copyright 2014 Jussi Pakkanen

# 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.

import typing as T
from pathlib import Path
import sys
import re
import argparse


class Token:
    def __init__(self, tid: str, value: str):
        self.tid = tid
        self.value = value
        self.lineno = 0
        self.colno = 0

class Statement:
    def __init__(self, name: str, args: list):
        self.name = name.lower()
        self.args = args

class Lexer:
    def __init__(self) -> None:
        self.token_specification = [
            # Need to be sorted longest to shortest.
            ('ignore', re.compile(r'[ \t]')),
            ('string', re.compile(r'"([^\\]|(\\.))*?"', re.M)),
            ('varexp', re.compile(r'\${[-_0-9a-z/A-Z.]+}')),
            ('id', re.compile('''[,-><${}=+_0-9a-z/A-Z|@.*]+''')),
            ('eol', re.compile(r'\n')),
            ('comment', re.compile(r'#.*')),
            ('lparen', re.compile(r'\(')),
            ('rparen', re.compile(r'\)')),
        ]

    def lex(self, code: str) -> T.Iterator[Token]:
        lineno = 1
        line_start = 0
        loc = 0
        col = 0
        while loc < len(code):
            matched = False
            for (tid, reg) in self.token_specification:
                mo = reg.match(code, loc)
                if mo:
                    col = mo.start() - line_start
                    matched = True
                    loc = mo.end()
                    match_text = mo.group()
                    if tid == 'ignore':
                        continue
                    if tid == 'comment':
                        yield(Token('comment', match_text))
                    elif tid == 'lparen':
                        yield(Token('lparen', '('))
                    elif tid == 'rparen':
                        yield(Token('rparen', ')'))
                    elif tid == 'string':
                        yield(Token('string', match_text[1:-1]))
                    elif tid == 'id':
                        yield(Token('id', match_text))
                    elif tid == 'eol':
                        # yield('eol')
                        lineno += 1
                        col = 1
                        line_start = mo.end()
                    elif tid == 'varexp':
                        yield(Token('varexp', match_text[2:-1]))
                    else:
                        raise ValueError(f'lex: unknown element {tid}')
                    break
            if not matched:
                raise ValueError('Lexer got confused line %d column %d' % (lineno, col))

class Parser:
    def __init__(self, code: str) -> None:
        self.stream = Lexer().lex(code)
        self.getsym()

    def getsym(self) -> None:
        try:
            self.current = next(self.stream)
        except StopIteration:
            self.current = Token('eof', '')

    def accept(self, s: str) -> bool:
        if self.current.tid == s:
            self.getsym()
            return True
        return False

    def expect(self, s: str) -> bool:
        if self.accept(s):
            return True
        raise ValueError(f'Expecting {s} got {self.current.tid}.', self.current.lineno, self.current.colno)

    def statement(self) -> Statement:
        cur = self.current
        if self.accept('comment'):
            return Statement('_', [cur.value])
        self.accept('id')
        self.expect('lparen')
        args = self.arguments()
        self.expect('rparen')
        return Statement(cur.value, args)

    def arguments(self) -> T.List[T.Union[Token, T.Any]]:
        args = []  # type: T.List[T.Union[Token, T.Any]]
        if self.accept('lparen'):
            args.append(self.arguments())
            self.expect('rparen')
        arg = self.current
        if self.accept('comment'):
            rest = self.arguments()
            args += rest
        elif self.accept('string') \
                or self.accept('varexp') \
                or self.accept('id'):
            args.append(arg)
            rest = self.arguments()
            args += rest
        return args

    def parse(self) -> T.Iterator[Statement]:
        while not self.accept('eof'):
            yield(self.statement())

def token_or_group(arg: T.Union[Token, T.List[Token]]) -> str:
    if isinstance(arg, Token):
        return ' ' + arg.value
    elif isinstance(arg, list):
        line = ' ('
        for a in arg:
            line += ' ' + token_or_group(a)
        line += ' )'
        return line
    raise RuntimeError('Conversion error in token_or_group')

class Converter:
    ignored_funcs = {'cmake_minimum_required': True,
                     'enable_testing': True,
                     'include': True}

    def __init__(self, cmake_root: str):
        self.cmake_root = Path(cmake_root).expanduser()
        self.indent_unit = '  '
        self.indent_level = 0
        self.options = []  # type: T.List[tuple]

    def convert_args(self, args: T.List[Token], as_array: bool = True) -> str:
        res = []
        if as_array:
            start = '['
            end = ']'
        else:
            start = ''
            end = ''
        for i in args:
            if i.tid == 'id':
                res.append("'%s'" % i.value)
            elif i.tid == 'varexp':
                res.append('%s' % i.value.lower())
            elif i.tid == 'string':
                res.append("'%s'" % i.value)
            else:
                raise ValueError(f'Unknown arg type {i.tid}')
        if len(res) > 1:
            return start + ', '.join(res) + end
        if len(res) == 1:
            return res[0]
        return ''

    def write_entry(self, outfile: T.TextIO, t: Statement) -> None:
        if t.name in Converter.ignored_funcs:
            return
        preincrement = 0
        postincrement = 0
        if t.name == '_':
            line = t.args[0]
        elif t.name == 'add_subdirectory':
            line = "subdir('" + t.args[0].value + "')"
        elif t.name == 'pkg_search_module' or t.name == 'pkg_search_modules':
            varname = t.args[0].value.lower()
            mods = ["dependency('%s')" % i.value for i in t.args[1:]]
            if len(mods) == 1:
                line = '{} = {}'.format(varname, mods[0])
            else:
                line = '{} = [{}]'.format(varname, ', '.join(["'%s'" % i for i in mods]))
        elif t.name == 'find_package':
            line = "{}_dep = dependency('{}')".format(t.args[0].value, t.args[0].value)
        elif t.name == 'find_library':
            line = "{} = find_library('{}')".format(t.args[0].value.lower(), t.args[0].value)
        elif t.name == 'add_executable':
            line = '{}_exe = executable({})'.format(t.args[0].value, self.convert_args(t.args, False))
        elif t.name == 'add_library':
            if t.args[1].value == 'SHARED':
                libcmd = 'shared_library'
                args = [t.args[0]] + t.args[2:]
            elif t.args[1].value == 'STATIC':
                libcmd = 'static_library'
                args = [t.args[0]] + t.args[2:]
            else:
                libcmd = 'library'
                args = t.args
            line = '{}_lib = {}({})'.format(t.args[0].value, libcmd, self.convert_args(args, False))
        elif t.name == 'add_test':
            line = 'test(%s)' % self.convert_args(t.args, False)
        elif t.name == 'option':
            optname = t.args[0].value
            description = t.args[1].value
            if len(t.args) > 2:
                default = t.args[2].value
            else:
                default = None
            self.options.append((optname, description, default))
            return
        elif t.name == 'project':
            pname = t.args[0].value
            args = [pname]
            for l in t.args[1:]:
                l = l.value.lower()
                if l == 'cxx':
                    l = 'cpp'
                args.append(l)
            args = ["'%s'" % i for i in args]
            line = 'project(' + ', '.join(args) + ", default_options : ['default_library=static'])"
        elif t.name == 'set':
            varname = t.args[0].value.lower()
            line = '{} = {}\n'.format(varname, self.convert_args(t.args[1:]))
        elif t.name == 'if':
            postincrement = 1
            try:
                line = 'if %s' % self.convert_args(t.args, False)
            except AttributeError:  # complex if statements
                line = t.name
                for arg in t.args:
                    line += token_or_group(arg)
        elif t.name == 'elseif':
            preincrement = -1
            postincrement = 1
            try:
                line = 'elif %s' % self.convert_args(t.args, False)
            except AttributeError:  # complex if statements
                line = t.name
                for arg in t.args:
                    line += token_or_group(arg)
        elif t.name == 'else':
            preincrement = -1
            postincrement = 1
            line = 'else'
        elif t.name == 'endif':
            preincrement = -1
            line = 'endif'
        else:
            line = '''# {}({})'''.format(t.name, self.convert_args(t.args))
        self.indent_level += preincrement
        indent = self.indent_level * self.indent_unit
        outfile.write(indent)
        outfile.write(line)
        if not(line.endswith('\n')):
            outfile.write('\n')
        self.indent_level += postincrement

    def convert(self, subdir: Path = None) -> None:
        if not subdir:
            subdir = self.cmake_root
        cfile = Path(subdir).expanduser() / 'CMakeLists.txt'
        try:
            with cfile.open() as f:
                cmakecode = f.read()
        except FileNotFoundError:
            print('\nWarning: No CMakeLists.txt in', subdir, '\n', file=sys.stderr)
            return
        p = Parser(cmakecode)
        with (subdir / 'meson.build').open('w') as outfile:
            for t in p.parse():
                if t.name == 'add_subdirectory':
                    # print('\nRecursing to subdir',
                    #       self.cmake_root / t.args[0].value,
                    #       '\n')
                    self.convert(subdir / t.args[0].value)
                    # print('\nReturning to', self.cmake_root, '\n')
                self.write_entry(outfile, t)
        if subdir == self.cmake_root and len(self.options) > 0:
            self.write_options()

    def write_options(self) -> None:
        filename = self.cmake_root / 'meson_options.txt'
        with filename.open('w') as optfile:
            for o in self.options:
                (optname, description, default) = o
                if default is None:
                    typestr = ''
                    defaultstr = ''
                else:
                    if default == 'OFF':
                        typestr = ' type : \'boolean\','
                        default = 'false'
                    elif default == 'ON':
                        default = 'true'
                        typestr = ' type : \'boolean\','
                    else:
                        typestr = ' type : \'string\','
                    defaultstr = ' value : %s,' % default
                line = "option({!r},{}{} description : '{}')\n".format(optname,
                                                                 typestr,
                                                                 defaultstr,
                                                                 description)
                optfile.write(line)

if __name__ == '__main__':
    p = argparse.ArgumentParser(description='Convert CMakeLists.txt to meson.build and meson_options.txt')
    p.add_argument('cmake_root', help='CMake project root (where top-level CMakeLists.txt is)')
    P = p.parse_args()

    Converter(P.cmake_root).convert()
