#!/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, list(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()
