import gc
import os
import tempfile

from clang.cindex import CursorKind
from clang.cindex import Cursor
from clang.cindex import File
from clang.cindex import Index
from clang.cindex import SourceLocation
from clang.cindex import SourceRange
from clang.cindex import TranslationUnitSaveError
from clang.cindex import TranslationUnitLoadError
from clang.cindex import TranslationUnit
from .util import get_cursor
from .util import get_tu

kInputsDir = os.path.join(os.path.dirname(__file__), 'INPUTS')

def test_spelling():
    path = os.path.join(kInputsDir, 'hello.cpp')
    tu = TranslationUnit.from_source(path)
    assert tu.spelling == path

def test_cursor():
    path = os.path.join(kInputsDir, 'hello.cpp')
    tu = get_tu(path)
    c = tu.cursor
    assert isinstance(c, Cursor)
    assert c.kind is CursorKind.TRANSLATION_UNIT

def test_parse_arguments():
    path = os.path.join(kInputsDir, 'parse_arguments.c')
    tu = TranslationUnit.from_source(path, ['-DDECL_ONE=hello', '-DDECL_TWO=hi'])
    spellings = [c.spelling for c in tu.cursor.get_children()]
    assert spellings[-2] == 'hello'
    assert spellings[-1] == 'hi'

def test_reparse_arguments():
    path = os.path.join(kInputsDir, 'parse_arguments.c')
    tu = TranslationUnit.from_source(path, ['-DDECL_ONE=hello', '-DDECL_TWO=hi'])
    tu.reparse()
    spellings = [c.spelling for c in tu.cursor.get_children()]
    assert spellings[-2] == 'hello'
    assert spellings[-1] == 'hi'

def test_unsaved_files():
    tu = TranslationUnit.from_source('fake.c', ['-I./'], unsaved_files = [
            ('fake.c', """
#include "fake.h"
int x;
int SOME_DEFINE;
"""),
            ('./fake.h', """
#define SOME_DEFINE y
""")
            ])
    spellings = [c.spelling for c in tu.cursor.get_children()]
    assert spellings[-2] == 'x'
    assert spellings[-1] == 'y'

def test_unsaved_files_2():
    try:
        from StringIO import StringIO
    except:
        from io import StringIO
    tu = TranslationUnit.from_source('fake.c', unsaved_files = [
            ('fake.c', StringIO('int x;'))])
    spellings = [c.spelling for c in tu.cursor.get_children()]
    assert spellings[-1] == 'x'

def normpaths_equal(path1, path2):
    """ Compares two paths for equality after normalizing them with
        os.path.normpath
    """
    return os.path.normpath(path1) == os.path.normpath(path2)

def test_includes():
    def eq(expected, actual):
        if not actual.is_input_file:
            return  normpaths_equal(expected[0], actual.source.name) and \
                    normpaths_equal(expected[1], actual.include.name)
        else:
            return normpaths_equal(expected[1], actual.include.name)

    src = os.path.join(kInputsDir, 'include.cpp')
    h1 = os.path.join(kInputsDir, "header1.h")
    h2 = os.path.join(kInputsDir, "header2.h")
    h3 = os.path.join(kInputsDir, "header3.h")
    inc = [(src, h1), (h1, h3), (src, h2), (h2, h3)]

    tu = TranslationUnit.from_source(src)
    for i in zip(inc, tu.get_includes()):
        assert eq(i[0], i[1])

def save_tu(tu):
    """Convenience API to save a TranslationUnit to a file.

    Returns the filename it was saved to.
    """
    _, path = tempfile.mkstemp()
    tu.save(path)

    return path

def test_save():
    """Ensure TranslationUnit.save() works."""

    tu = get_tu('int foo();')

    path = save_tu(tu)
    assert os.path.exists(path)
    assert os.path.getsize(path) > 0
    os.unlink(path)

def test_save_translation_errors():
    """Ensure that saving to an invalid directory raises."""

    tu = get_tu('int foo();')

    path = '/does/not/exist/llvm-test.ast'
    assert not os.path.exists(os.path.dirname(path))

    try:
        tu.save(path)
        assert False
    except TranslationUnitSaveError as ex:
        expected = TranslationUnitSaveError.ERROR_UNKNOWN
        assert ex.save_error == expected

def test_load():
    """Ensure TranslationUnits can be constructed from saved files."""

    tu = get_tu('int foo();')
    assert len(tu.diagnostics) == 0
    path = save_tu(tu)

    assert os.path.exists(path)
    assert os.path.getsize(path) > 0

    tu2 = TranslationUnit.from_ast_file(filename=path)
    assert len(tu2.diagnostics) == 0

    foo = get_cursor(tu2, 'foo')
    assert foo is not None

    # Just in case there is an open file descriptor somewhere.
    del tu2

    os.unlink(path)

def test_index_parse():
    path = os.path.join(kInputsDir, 'hello.cpp')
    index = Index.create()
    tu = index.parse(path)
    assert isinstance(tu, TranslationUnit)

def test_get_file():
    """Ensure tu.get_file() works appropriately."""

    tu = get_tu('int foo();')

    f = tu.get_file('t.c')
    assert isinstance(f, File)
    assert f.name == 't.c'

    try:
        f = tu.get_file('foobar.cpp')
    except:
        pass
    else:
        assert False

def test_get_source_location():
    """Ensure tu.get_source_location() works."""

    tu = get_tu('int foo();')

    location = tu.get_location('t.c', 2)
    assert isinstance(location, SourceLocation)
    assert location.offset == 2
    assert location.file.name == 't.c'

    location = tu.get_location('t.c', (1, 3))
    assert isinstance(location, SourceLocation)
    assert location.line == 1
    assert location.column == 3
    assert location.file.name == 't.c'

def test_get_source_range():
    """Ensure tu.get_source_range() works."""

    tu = get_tu('int foo();')

    r = tu.get_extent('t.c', (1,4))
    assert isinstance(r, SourceRange)
    assert r.start.offset == 1
    assert r.end.offset == 4
    assert r.start.file.name == 't.c'
    assert r.end.file.name == 't.c'

    r = tu.get_extent('t.c', ((1,2), (1,3)))
    assert isinstance(r, SourceRange)
    assert r.start.line == 1
    assert r.start.column == 2
    assert r.end.line == 1
    assert r.end.column == 3
    assert r.start.file.name == 't.c'
    assert r.end.file.name == 't.c'

    start = tu.get_location('t.c', 0)
    end = tu.get_location('t.c', 5)

    r = tu.get_extent('t.c', (start, end))
    assert isinstance(r, SourceRange)
    assert r.start.offset == 0
    assert r.end.offset == 5
    assert r.start.file.name == 't.c'
    assert r.end.file.name == 't.c'

def test_get_tokens_gc():
    """Ensures get_tokens() works properly with garbage collection."""

    tu = get_tu('int foo();')
    r = tu.get_extent('t.c', (0, 10))
    tokens = list(tu.get_tokens(extent=r))

    assert tokens[0].spelling == 'int'
    gc.collect()
    assert tokens[0].spelling == 'int'

    del tokens[1]
    gc.collect()
    assert tokens[0].spelling == 'int'

    # May trigger segfault if we don't do our job properly.
    del tokens
    gc.collect()
    gc.collect() # Just in case.

def test_fail_from_source():
    path = os.path.join(kInputsDir, 'non-existent.cpp')
    try:
        tu = TranslationUnit.from_source(path)
    except TranslationUnitLoadError:
        tu = None
    assert tu == None

def test_fail_from_ast_file():
    path = os.path.join(kInputsDir, 'non-existent.ast')
    try:
        tu = TranslationUnit.from_ast_file(path)
    except TranslationUnitLoadError:
        tu = None
    assert tu == None
