// Copyright (c) 2020, 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 'dart:io';

import 'package:ffigen/src/code_generator.dart';
import 'package:test/test.dart';

void main() {
  group('code_generator: ', () {
    test('Function Binding (primitives, pointers)', () {
      final library = Library(
        name: 'Bindings',
        bindings: [
          Func(
            name: 'noParam',
            lookupSymbolName: 'noParam',
            dartDoc: 'Just a test function\nheres another line',
            returnType: Type.nativeType(
              SupportedNativeType.Int32,
            ),
          ),
          Func(
            name: 'withPrimitiveParam',
            lookupSymbolName: 'withPrimitiveParam',
            parameters: [
              Parameter(
                name: 'a',
                type: Type.nativeType(
                  SupportedNativeType.Int32,
                ),
              ),
              Parameter(
                name: 'b',
                type: Type.nativeType(
                  SupportedNativeType.Uint8,
                ),
              ),
            ],
            returnType: Type.nativeType(
              SupportedNativeType.Char,
            ),
          ),
          Func(
            name: 'withPointerParam',
            lookupSymbolName: 'withPointerParam',
            parameters: [
              Parameter(
                name: 'a',
                type: Type.pointer(
                  Type.nativeType(
                    SupportedNativeType.Int32,
                  ),
                ),
              ),
              Parameter(
                name: 'b',
                type: Type.pointer(
                  Type.pointer(
                    Type.nativeType(
                      SupportedNativeType.Uint8,
                    ),
                  ),
                ),
              ),
            ],
            returnType: Type.pointer(
              Type.nativeType(
                SupportedNativeType.Double,
              ),
            ),
          ),
        ],
      );

      final gen = library.generate();

      // Writing to file for debug purpose.
      final file = File(
        'test/debug_generated/Function-Binding-test-output.dart',
      );
      try {
        expect(gen, '''/// AUTO GENERATED FILE, DO NOT EDIT.
/// 
/// Generated by `package:ffigen`.
import 'dart:ffi' as ffi;

class Bindings{
/// Holds the Dynamic library.
final ffi.DynamicLibrary _dylib;

/// The symbols are looked up in [dynamicLibrary].
Bindings(ffi.DynamicLibrary dynamicLibrary): _dylib = dynamicLibrary;

/// Just a test function
/// heres another line
int noParam(
) {
_noParam ??= _dylib.lookupFunction<_c_noParam,_dart_noParam>('noParam');
  return _noParam(
  );
}
_dart_noParam _noParam;

int withPrimitiveParam(
  int a,
  int b,
) {
_withPrimitiveParam ??= _dylib.lookupFunction<_c_withPrimitiveParam,_dart_withPrimitiveParam>('withPrimitiveParam');
  return _withPrimitiveParam(
    a,
    b,
  );
}
_dart_withPrimitiveParam _withPrimitiveParam;

ffi.Pointer<ffi.Double> withPointerParam(
  ffi.Pointer<ffi.Int32> a,
  ffi.Pointer<ffi.Pointer<ffi.Uint8>> b,
) {
_withPointerParam ??= _dylib.lookupFunction<_c_withPointerParam,_dart_withPointerParam>('withPointerParam');
  return _withPointerParam(
    a,
    b,
  );
}
_dart_withPointerParam _withPointerParam;

}

typedef _c_noParam = ffi.Int32 Function(
);

typedef _dart_noParam = int Function(
);

typedef _c_withPrimitiveParam = ffi.Uint8 Function(
  ffi.Int32 a,
  ffi.Uint8 b,
);

typedef _dart_withPrimitiveParam = int Function(
  int a,
  int b,
);

typedef _c_withPointerParam = ffi.Pointer<ffi.Double> Function(
  ffi.Pointer<ffi.Int32> a,
  ffi.Pointer<ffi.Pointer<ffi.Uint8>> b,
);

typedef _dart_withPointerParam = ffi.Pointer<ffi.Double> Function(
  ffi.Pointer<ffi.Int32> a,
  ffi.Pointer<ffi.Pointer<ffi.Uint8>> b,
);

''');
        if (file.existsSync()) {
          file.delete();
        }
      } catch (e) {
        file.writeAsStringSync(gen);
        print('Failed test, Debug output: ${file.absolute?.path}');
        rethrow;
      }
    });

    test('Struct Binding (primitives, pointers)', () {
      final library = Library(
        name: 'Bindings',
        bindings: [
          Struc(
            name: 'NoMember',
            dartDoc: 'Just a test struct\nheres another line',
          ),
          Struc(
            name: 'WithPrimitiveMember',
            members: [
              Member(
                name: 'a',
                type: Type.nativeType(
                  SupportedNativeType.Int32,
                ),
              ),
              Member(
                name: 'b',
                type: Type.nativeType(
                  SupportedNativeType.Double,
                ),
              ),
              Member(
                name: 'c',
                type: Type.nativeType(
                  SupportedNativeType.Char,
                ),
              ),
            ],
          ),
          Struc(
            name: 'WithPointerMember',
            members: [
              Member(
                name: 'a',
                type: Type.pointer(
                  Type.nativeType(
                    SupportedNativeType.Int32,
                  ),
                ),
              ),
              Member(
                name: 'b',
                type: Type.pointer(
                  Type.pointer(
                    Type.nativeType(
                      SupportedNativeType.Double,
                    ),
                  ),
                ),
              ),
              Member(
                name: 'c',
                type: Type.nativeType(
                  SupportedNativeType.Char,
                ),
              ),
            ],
          ),
        ],
      );

      final gen = library.generate();

      // Writing to file for debug purpose.
      final file = File('test/debug_generated/Struct-Binding-test-output.dart');

      try {
        expect(gen, '''/// AUTO GENERATED FILE, DO NOT EDIT.
/// 
/// Generated by `package:ffigen`.
import 'dart:ffi' as ffi;

/// Just a test struct
/// heres another line
class NoMember extends ffi.Struct{
}

class WithPrimitiveMember extends ffi.Struct{
  @ffi.Int32()
  int a;

  @ffi.Double()
  double b;

  @ffi.Uint8()
  int c;

}

class WithPointerMember extends ffi.Struct{
  ffi.Pointer<ffi.Int32> a;

  ffi.Pointer<ffi.Pointer<ffi.Double>> b;

  @ffi.Uint8()
  int c;

}

''');
        if (file.existsSync()) {
          file.delete();
        }
      } catch (e) {
        file.writeAsStringSync(gen);
        print('Failed test, Debug output: ${file.absolute?.path}');
        rethrow;
      }
    });

    test('Function and Struct Binding (pointer to Struct)', () {
      final struct_some = Struc(
        name: 'SomeStruc',
        members: [
          Member(
            name: 'a',
            type: Type.nativeType(
              SupportedNativeType.Int32,
            ),
          ),
          Member(
            name: 'b',
            type: Type.nativeType(
              SupportedNativeType.Double,
            ),
          ),
          Member(
            name: 'c',
            type: Type.nativeType(
              SupportedNativeType.Char,
            ),
          ),
        ],
      );
      final library = Library(
        name: 'Bindings',
        bindings: [
          struct_some,
          Func(
            name: 'someFunc',
            lookupSymbolName: 'someFunc',
            parameters: [
              Parameter(
                name: 'some',
                type: Type.pointer(
                  Type.pointer(
                    Type.struct(
                      struct_some,
                    ),
                  ),
                ),
              ),
            ],
            returnType: Type.pointer(
              Type.struct(
                struct_some,
              ),
            ),
          ),
        ],
      );

      final gen = library.generate();

      // Writing to file for debug purpose.
      final file =
          File('test/debug_generated/Func-n-Struct-Binding-test-output.dart');
      try {
        //expect
        expect(gen, '''/// AUTO GENERATED FILE, DO NOT EDIT.
/// 
/// Generated by `package:ffigen`.
import 'dart:ffi' as ffi;

class Bindings{
/// Holds the Dynamic library.
final ffi.DynamicLibrary _dylib;

/// The symbols are looked up in [dynamicLibrary].
Bindings(ffi.DynamicLibrary dynamicLibrary): _dylib = dynamicLibrary;

ffi.Pointer<SomeStruc> someFunc(
  ffi.Pointer<ffi.Pointer<SomeStruc>> some,
) {
_someFunc ??= _dylib.lookupFunction<_c_someFunc,_dart_someFunc>('someFunc');
  return _someFunc(
    some,
  );
}
_dart_someFunc _someFunc;

}

class SomeStruc extends ffi.Struct{
  @ffi.Int32()
  int a;

  @ffi.Double()
  double b;

  @ffi.Uint8()
  int c;

}

typedef _c_someFunc = ffi.Pointer<SomeStruc> Function(
  ffi.Pointer<ffi.Pointer<SomeStruc>> some,
);

typedef _dart_someFunc = ffi.Pointer<SomeStruc> Function(
  ffi.Pointer<ffi.Pointer<SomeStruc>> some,
);

''');
        if (file.existsSync()) {
          file.delete();
        }
      } catch (e) {
        file.writeAsStringSync(gen);
        print('Failed test, Debug output: ${file.absolute?.path}');
        rethrow;
      }
    });

    test('global (primitives, pointers, pointer to struct)', () {
      final struc_some = Struc(
        name: 'Some',
      );
      final library = Library(
        name: 'Bindings',
        bindings: [
          Global(
            name: 'test1',
            lookupSymbolName: 'test1',
            type: Type.nativeType(
              SupportedNativeType.Int32,
            ),
          ),
          Global(
            name: 'test2',
            lookupSymbolName: 'test2',
            type: Type.pointer(
              Type.nativeType(
                SupportedNativeType.Float,
              ),
            ),
          ),
          struc_some,
          Global(
            name: 'test5',
            lookupSymbolName: 'test5',
            type: Type.pointer(
              Type.struct(
                struc_some,
              ),
            ),
          ),
        ],
      );

      final gen = library.generate();

      // Writing to file for debug purpose.
      final file = File(
        'test/debug_generated/Global-Binding-test-output.dart',
      );
      try {
        expect(gen, '''/// AUTO GENERATED FILE, DO NOT EDIT.
/// 
/// Generated by `package:ffigen`.
import 'dart:ffi' as ffi;

class Bindings{
/// Holds the Dynamic library.
final ffi.DynamicLibrary _dylib;

/// The symbols are looked up in [dynamicLibrary].
Bindings(ffi.DynamicLibrary dynamicLibrary): _dylib = dynamicLibrary;

ffi.Pointer<ffi.Int32> _test1;
int get test1 => (_test1 ??= _dylib.lookup<ffi.Int32>('test1')).value;

ffi.Pointer<ffi.Pointer<ffi.Float>> _test2;
ffi.Pointer<ffi.Float> get test2 => (_test2 ??= _dylib.lookup<ffi.Pointer<ffi.Float>>('test2')).value;

ffi.Pointer<ffi.Pointer<Some>> _test5;
ffi.Pointer<Some> get test5 => (_test5 ??= _dylib.lookup<ffi.Pointer<Some>>('test5')).value;

}

class Some extends ffi.Struct{
}

''');
        if (file.existsSync()) {
          file.delete();
        }
      } catch (e) {
        file.writeAsStringSync(gen);
        print('Failed test, Debug output: ${file.absolute?.path}');
        rethrow;
      }
    });

    test('constant', () {
      final library = Library(
        name: 'Bindings',
        bindings: [
          Constant(
            name: 'test1',
            type: Type.nativeType(
              SupportedNativeType.Int32,
            ),
            rawValue: '20',
          ),
          Constant(
            name: 'test2',
            type: Type.nativeType(
              SupportedNativeType.Float,
            ),
            rawValue: '20.0',
          ),
        ],
      );

      final gen = library.generate();

      // Writing to file for debug purpose.
      final file = File(
        'test/debug_generated/Constant-test-output.dart',
      );
      try {
        expect(gen, '''/// AUTO GENERATED FILE, DO NOT EDIT.
/// 
/// Generated by `package:ffigen`.
import 'dart:ffi' as ffi;

const int test1 = 20;

const double test2 = 20.0;

''');
        if (file.existsSync()) {
          file.delete();
        }
      } catch (e) {
        file.writeAsStringSync(gen);
        print('Failed test, Debug output: ${file.absolute?.path}');
        rethrow;
      }
    });

    test('enum_class', () {
      final library = Library(
        name: 'Bindings',
        bindings: [
          EnumClass(
            name: 'Constants',
            dartDoc: 'test line 1\ntest line 2',
            enumConstants: [
              EnumConstant(
                name: 'a',
                value: 10,
              ),
              EnumConstant(name: 'b', value: -1, dartDoc: 'negative'),
            ],
          ),
        ],
      );

      final gen = library.generate();

      // Writing to file for debug purpose.
      final file = File(
        'test/debug_generated/enum-class-test-output.dart',
      );
      try {
        expect(gen, '''/// AUTO GENERATED FILE, DO NOT EDIT.
/// 
/// Generated by `package:ffigen`.
import 'dart:ffi' as ffi;

/// test line 1
/// test line 2
class Constants {
  static const int a = 10;
  /// negative
  static const int b = -1;
}

''');
        if (file.existsSync()) {
          file.delete();
        }
      } catch (e) {
        file.writeAsStringSync(gen);
        print('Failed test, Debug output: ${file.absolute?.path}');
        rethrow;
      }
    });
    test('Internal conflict resolution', () {
      final library = Library(
        name: 'init_dylib',
        bindings: [
          Func(
            name: 'test',
            lookupSymbolName: 'test',
            returnType: Type.nativeType(SupportedNativeType.Void),
          ),
          Func(
            name: '_test',
            lookupSymbolName: '_test',
            returnType: Type.nativeType(SupportedNativeType.Void),
          ),
          Func(
            name: '_c_test',
            lookupSymbolName: '_c_test',
            returnType: Type.nativeType(SupportedNativeType.Void),
          ),
          Func(
            name: '_dart_test',
            lookupSymbolName: '_dart_test',
            returnType: Type.nativeType(SupportedNativeType.Void),
          ),
          Struc(
            name: '_Test',
            members: [
              Member(
                name: 'array',
                type: Type.constantArray(
                  2,
                  Type.nativeType(
                    SupportedNativeType.Int8,
                  ),
                ),
              ),
            ],
          ),
          Struc(name: 'ArrayHelperPrefixCollisionTest'),
          Func(
            name: 'Test',
            lookupSymbolName: 'Test',
            returnType: Type.nativeType(SupportedNativeType.Void),
          ),
          EnumClass(name: '_c_Test'),
          EnumClass(name: 'init_dylib'),
        ],
      );

      final gen = library.generate();

      // Writing to file for debug purpose.
      final file = File(
        'test/debug_generated/internal-conflict-resolution.dart',
      );
      try {
        expect(gen, r'''/// AUTO GENERATED FILE, DO NOT EDIT.
/// 
/// Generated by `package:ffigen`.
import 'dart:ffi' as ffi;

class init_dylib_1{
/// Holds the Dynamic library.
final ffi.DynamicLibrary _dylib;

/// The symbols are looked up in [dynamicLibrary].
init_dylib_1(ffi.DynamicLibrary dynamicLibrary): _dylib = dynamicLibrary;

void test(
) {
_test_1 ??= _dylib.lookupFunction<_c_test1,_dart_test1>('test');
  return _test_1(
  );
}
_dart_test1 _test_1;

void _test(
) {
__test ??= _dylib.lookupFunction<_c__test,_dart__test>('_test');
  return __test(
  );
}
_dart__test __test;

void _c_test(
) {
__c_test ??= _dylib.lookupFunction<_c__c_test,_dart__c_test>('_c_test');
  return __c_test(
  );
}
_dart__c_test __c_test;

void _dart_test(
) {
__dart_test ??= _dylib.lookupFunction<_c__dart_test,_dart__dart_test>('_dart_test');
  return __dart_test(
  );
}
_dart__dart_test __dart_test;

void Test(
) {
_Test ??= _dylib.lookupFunction<_c_Test1,_dart_Test>('Test');
  return _Test(
  );
}
_dart_Test _Test;

}

class _Test extends ffi.Struct{
  @ffi.Int8()
  int _unique_array_item_0;
  @ffi.Int8()
  int _unique_array_item_1;
/// Helper for array `array`.
ArrayHelper1__Test_array_level0 get array => ArrayHelper1__Test_array_level0(this, [2], 0, 0);
}

/// Helper for array `array` in struct `_Test`.
class ArrayHelper1__Test_array_level0{
final _Test _struct;
final List<int> dimensions;
final int level;
final int _absoluteIndex;
int get length => dimensions[level];
ArrayHelper1__Test_array_level0(this._struct, this.dimensions, this.level, this._absoluteIndex);
  void _checkBounds(int index) {
    if (index >= length || index < 0) {
      throw RangeError('Dimension $level: index not in range 0..${length} exclusive.');
    }
  }
  int operator[](int index){
_checkBounds(index);
switch(_absoluteIndex+index){
case 0:
  return _struct._unique_array_item_0;
case 1:
  return _struct._unique_array_item_1;
default:
  throw Exception('Invalid Array Helper generated.');}
}
void operator[]=(int index, int value){
_checkBounds(index);
switch(_absoluteIndex+index){
case 0:
  _struct._unique_array_item_0 = value;
  break;
case 1:
  _struct._unique_array_item_1 = value;
  break;
default:
  throw Exception('Invalid Array Helper generated.');
}
}
}
class ArrayHelperPrefixCollisionTest extends ffi.Struct{
}

class _c_Test {
}

class init_dylib {
}

typedef _c_test1 = ffi.Void Function(
);

typedef _dart_test1 = void Function(
);

typedef _c__test = ffi.Void Function(
);

typedef _dart__test = void Function(
);

typedef _c__c_test = ffi.Void Function(
);

typedef _dart__c_test = void Function(
);

typedef _c__dart_test = ffi.Void Function(
);

typedef _dart__dart_test = void Function(
);

typedef _c_Test1 = ffi.Void Function(
);

typedef _dart_Test = void Function(
);

''');
        if (file.existsSync()) {
          file.delete();
        }
      } catch (e) {
        file.writeAsStringSync(gen);
        print('Failed test, Debug output: ${file.absolute?.path}');
        rethrow;
      }
    });
  });
}
