#!/usr/bin/env python3
# Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

import database
import idlparser
import logging.config
import os
import os.path
import shutil
import tempfile
import unittest
from databasebuilder import *


class DatabaseBuilderTestCase(unittest.TestCase):

    def _create_input(self, idl_file_name, content):
        file_name = os.path.join(self._input_dir, idl_file_name)
        f = open(file_name, 'w')
        f.write(content)
        f.close()
        return file_name

    def _assert_interface_exists(self, path):
        file_path = os.path.join(self._database_dir, path)
        self.assertTrue(os.path.exists(file_path))

    def _assert_content_equals(self, path, expected_content):

        def clean(content):
            return ' '.join(filter(len, map(str.strip, content.split('\n'))))

        file_path = os.path.join(self._database_dir, path)
        self.assertTrue(os.path.exists(file_path))
        f = open(file_path, 'r')
        actual_content = f.read()
        f.close()
        if clean(actual_content) != clean(expected_content):
            msg = '''
FILE: %s
EXPECTED:
%s
ACTUAL:
%s
''' % (file_path, expected_content, actual_content)
            self.fail(msg)

    def setUp(self):
        working_dir = tempfile.mkdtemp()
        self._database_dir = os.path.join(working_dir, 'database')
        self.assertFalse(os.path.exists(self._database_dir))

        self._input_dir = os.path.join(working_dir, 'inputdir')
        os.makedirs(self._input_dir)

        self._db = database.Database(self._database_dir)
        self.assertTrue(os.path.exists(self._database_dir))

        self._builder = DatabaseBuilder(self._db)

    def tearDown(self):
        shutil.rmtree(self._database_dir)

    def test_basic_import(self):
        file_name = self._create_input(
            'input.idl', '''
      module M {
        interface I {
          attribute int a;
        };
      };''')
        self._builder.import_idl_file(file_name)
        self._builder.merge_imported_interfaces([])
        self._db.Save()
        self._assert_interface_exists('I.idl')

    def test_splitting(self):
        file_name = self._create_input(
            'input.idl', '''
      module M {
        interface I {
          readonly attribute int a;
          int o(in int x, in optional int y);
        };
      };''')
        self._builder.import_idl_file(file_name)
        self._builder.merge_imported_interfaces([])
        self._db.Save()
        self._assert_content_equals(
            'I.idl', '''
      interface I {
        /* Attributes */
        getter attribute int a;

        /* Operations */
        int o(in int x);
        int o(in int x, in int y);
      };''')

    def test_renames(self):
        file_name = self._create_input(
            'input.idl', '''
      module M {
        [Constructor(in T x)] interface I {
          T op(T x);
          readonly attribute N::T attr;
        };
      };''')
        options = DatabaseBuilderOptions(type_rename_map={'I': 'i', 'T': 't'})
        self._builder.import_idl_file(file_name, options)
        self._builder.merge_imported_interfaces([])
        self._db.Save()
        self._assert_content_equals(
            'i.idl', '''
      [Constructor(in t x)] interface i {
        /* Attributes */
        getter attribute t attr;
        /* Operations */
        t op(in t x);
      };''')

    def test_type_defs(self):
        file_name = self._create_input(
            'input.idl', '''
      module M {
        typedef T S;
        interface I : S {
          S op(S x);
          readonly attribute S attr;
        };
      };''')
        options = DatabaseBuilderOptions()
        self._builder.import_idl_file(file_name, options)
        self._builder.merge_imported_interfaces([])
        self._db.Save()
        self._assert_content_equals(
            'I.idl', '''
      interface I :
        T {
        /* Attributes */
        getter attribute T attr;
        /* Operations */
        T op(in T x);
      };''')

    def test_merge(self):
        file_name1 = self._create_input(
            'input1.idl', '''
      module M {
        interface I {
          const int CONST_BOTH = 0;
          const int CONST_ONLY_FIRST = 0;
          const int CONST_BOTH_DIFFERENT_VALUE = 0;

          readonly attribute int attr_only_first;
          readonly attribute int attr_both;
          readonly attribute int attr_both_readonly_difference;
          readonly attribute int attr_both_int_long_difference;

          int op_only_first();
          int op_both(int a);
          int op_both_optionals_difference(int a,
            in optional int b);
          int op_both_arg_rename(int arg);
        };
      };''')
        self._builder.import_idl_file(
            file_name1,
            DatabaseBuilderOptions(
                source='1st', idl_syntax=idlparser.FREMONTCUT_SYNTAX))
        file_name2 = self._create_input(
            'input2.idl', '''
      module M {
        interface I {
          const int CONST_BOTH = 0;
          const int CONST_ONLY_SECOND = 0;
          const int CONST_BOTH_DIFFERENT_VALUE = 1;

          readonly attribute int attr_only_second;
          readonly attribute int attr_both;
          readonly attribute long attr_both_int_long_difference;
          attribute int attr_both_readonly_difference;

          int op_only_second();
          int op_both(int a);
          int op_both_optionals_difference(int a,
            optional boolean b);
          int op_both_arg_rename(int betterName);
        };
      };''')
        self._builder.import_idl_file(
            file_name2,
            DatabaseBuilderOptions(
                source='2nd', idl_syntax=idlparser.FREMONTCUT_SYNTAX))
        self._builder.set_same_signatures({'int': 'long'})
        self._builder.merge_imported_interfaces([])
        self._db.Save()
        self._assert_content_equals(
            'I.idl', '''
      @1st(module=M) @2nd(module=M) interface I {
        /* Constants */
        @1st @2nd const int CONST_BOTH = 0;
        @1st const int CONST_BOTH_DIFFERENT_VALUE = 0;
        @2nd const int CONST_BOTH_DIFFERENT_VALUE = 1;
        @1st const int CONST_ONLY_FIRST = 0;
        @2nd const int CONST_ONLY_SECOND = 0;

        /* Attributes */
        @1st @2nd getter attribute int attr_both;
        @1st @2nd getter attribute int attr_both_int_long_difference;
        @1st @2nd getter attribute int attr_both_readonly_difference;
        @2nd setter attribute int attr_both_readonly_difference;
        @1st getter attribute int attr_only_first;
        @2nd getter attribute int attr_only_second;

        /* Operations */
        @1st @2nd int op_both(in t a);
        @1st @2nd int op_both_arg_rename(in t betterName);
        @1st @2nd int op_both_optionals_difference(in t a);
        @1st int op_both_optionals_difference(in t a, in int b);
        @2nd int op_both_optionals_difference(in t a, in boolean b);
        @1st int op_only_first();
        @2nd int op_only_second();
      };''')

    def test_mergeDartName(self):
        file_name1 = self._create_input(
            'input1.idl', '''
      module M {
        interface I {
          [ImplementationFunction=foo] int member(in int a);
        };
      };''')
        self._builder.import_idl_file(
            file_name1,
            DatabaseBuilderOptions(
                source='1st', idl_syntax=idlparser.FREMONTCUT_SYNTAX))
        file_name2 = self._create_input(
            'input2.idl', '''
      module M {
        interface I {
          [DartName=bar] int member(in int a);
        };
      };''')
        self._builder.import_idl_file(
            file_name2,
            DatabaseBuilderOptions(
                source='2nd', idl_syntax=idlparser.FREMONTCUT_SYNTAX))
        self._builder.merge_imported_interfaces([])
        self._db.Save()
        self._assert_content_equals(
            'I.idl', '''
      @1st(module=M) @2nd(module=M) interface I {
        /* Operations */
        @1st @2nd [DartName=bar, ImplementationFunction=foo] int member(in int a);
      };''')

    def test_supplemental(self):
        file_name = self._create_input(
            'input1.idl', '''
      module M {
        interface I {
          readonly attribute int a;
        };
        [Supplemental] interface I {
          readonly attribute int b;
        };
      };''')
        self._builder.import_idl_file(file_name,
                                      DatabaseBuilderOptions(source='Src'))
        self._builder.merge_imported_interfaces([])
        self._db.Save()
        self._assert_content_equals(
            'I.idl', '''
      @Src(module=M) [Supplemental] interface I {
        /* Attributes */
        @Src getter attribute int a;
        @Src getter attribute int b;
      };''')

    def test_impl_stmt(self):
        file_name = self._create_input(
            'input.idl', '''
      module M {
        interface I {};
        I implements J;
      };''')
        self._builder.import_idl_file(file_name,
                                      DatabaseBuilderOptions(source='Src'))
        self._builder.merge_imported_interfaces([])
        self._db.Save()
        self._assert_content_equals(
            'I.idl', '''
      @Src(module=M) interface I :
        @Src J {
      };''')

    def test_obsolete(self):
        file_name1 = self._create_input(
            'input1.idl', '''
      module M {
        interface I {
          readonly attribute int keep;
          readonly attribute int obsolete; // Would be removed
        };
      };''')
        self._builder.import_idl_file(file_name1,
                                      DatabaseBuilderOptions(source='src'))
        file_name2 = self._create_input(
            'input2.idl', '''
      module M {
        interface I {
          readonly attribute int keep;
          readonly attribute int new;
        };
      };''')
        self._builder.import_idl_file(
            file_name2,
            DatabaseBuilderOptions(
                source='src', obsolete_old_declarations=True))
        self._builder.merge_imported_interfaces([])
        self._db.Save()
        self._assert_content_equals(
            'I.idl', '''
      @src(module=M) interface I {
        /* Attributes */
        @src getter attribute int keep;
        @src getter attribute int new;
      };''')

    def test_annotation_normalization(self):
        file_name = self._create_input(
            'input.idl', '''
      module M {
        interface I : J{
          const int C = 0;
          readonly attribute int a;
          int op();
        };
      };''')
        self._builder.import_idl_file(
            file_name,
            DatabaseBuilderOptions(source='Src', source_attributes={'x': 'y'}))
        self._builder.merge_imported_interfaces([])
        interface = self._db.GetInterface('I')
        interface.parents[0].annotations['Src']['x'] = 'u'
        interface.constants[0].annotations['Src']['z'] = 'w'
        interface.attributes[0].annotations['Src']['x'] = 'u'
        self._db.Save()

        # Before normalization
        self._assert_content_equals(
            'I.idl', '''
      @Src(module=M, x=y)
      interface I : @Src(x=u) J {
        /* Constants */
        @Src(x=y, z=w) const int C = 0;
        /* Attributes */
        @Src(x=u) getter attribute int a;
        /* Operations */
        @Src(x=y) int op();
      };''')

        # Normalize
        self._builder.normalize_annotations(['Src'])
        self._db.Save()

        # After normalization
        self._assert_content_equals(
            'I.idl', '''
      @Src(module=M, x=y)
      interface I : @Src(x=u) J {
        /* Constants */
        @Src(z=w) const int C = 0;
        /* Attributes */
        @Src(x=u) getter attribute int a;
        /* Operations */
        @Src int op();
      };''')

    def test_fix_displacements(self):
        file_name1 = self._create_input(
            'input1.idl', '''
      module M {
        interface I {};
        interface J : I {
          readonly attribute int attr;
        };
      };''')
        self._builder.import_idl_file(file_name1,
                                      DatabaseBuilderOptions(source='1st'))
        file_name2 = self._create_input(
            'input2.idl', '''
      module M {
        interface I {
          readonly attribute int attr;
        };
        interface J : I {};
      };''')
        self._builder.import_idl_file(file_name2,
                                      DatabaseBuilderOptions(source='2nd'))
        self._builder.merge_imported_interfaces([])
        self._builder.fix_displacements('2nd')
        self._db.Save()
        self._assert_content_equals(
            'J.idl', '''
      @1st(module=M) @2nd(module=M) interface J :
        @1st @2nd I {
        /* Attributes */
        @1st
        @2nd(via=I)
        getter attribute int attr;
      };''')


if __name__ == "__main__":
    logging.config.fileConfig("logging.conf")
    if __name__ == '__main__':
        unittest.main()
