#!/usr/bin/python
# 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()
