"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/* eslint-disable no-param-reassign */
/* eslint-disable max-classes-per-file */
const core_1 = require("@il2js/core");
const Codegen_1 = require("./Codegen");
const Types_1 = require("./Types");
describe('codegen', () => {
    it('with no typelib', async () => {
        const writeFile = jest.fn((_path, _value) => Promise.resolve());
        const load = jest.fn();
        const gasm = {
            cached: false,
            gameAssemblyDllPath: 'foo/TestGameAssembly.dll',
            globalMetadataPath: 'foo/metadata/globalMetadata.dat',
            load,
            version: '123',
            structs: {
                TypeInfoList: [
                    Types_1.mockIl2CppTypeDefinitionInfo({ TypeName: 'Bar', Namespace: 'Test', TypeIndex: 1 }, {
                        ImageName: 'image',
                        Fields: [
                            {
                                Type: Types_1.mockIl2CppTypeInfo({ TypeName: 'int', Indirection: 1, IsPrimitive: true }),
                                Name: 'value',
                                Offset: 0x8,
                            },
                        ],
                    }),
                    Types_1.mockIl2CppTypeDefinitionInfo({ TypeName: 'Foo', Namespace: 'Test', TypeIndex: 2 }, {
                        ImageName: 'image',
                        Fields: [
                            {
                                Type: Types_1.mockIl2CppTypeInfo({ TypeName: 'Bar', Namespace: 'Test', Indirection: 1, TypeIndex: 1 }),
                                Name: 'bar',
                                Offset: 0x8,
                            },
                        ],
                    }),
                ],
                TypeNameToStaticMethods: {
                    'Test.Foo': [{ Address: 1234, Name: 'get_instance' }],
                },
            },
        };
        await Codegen_1.codegen({
            gasm,
            output: {
                entry: 'index.ts',
                outputDir: 'out',
            },
            targets: [['typescript', { rootNamespace: 'codegen' }]],
            api: { writeFile },
            types: [],
        });
        expect(writeFile.mock.calls[0]).toMatchInlineSnapshot(`
      Array [
        "out\\\\index.ts",
        "import { Address, TypeName, bindTypeArgs } from \\"@il2js/core\\";
      export const GameAssemblyInfo = {
          assemblyName: \\"TestGameAssembly.dll\\",
          version: \\"123\\"
      };
      export namespace codegen.Test {
          export class Bar extends il2js.NativeStruct {
              public static [TypeName] = \\"codegen.Test.Bar\\";
              static get size() { return 8 + il2js.NativeStruct.sizeof(\\"int\\"); }
              public static fieldNames: string[] = [\\"value\\"];
              public get value(): number {
                  return this.readTypePrimitive(8, \\"int\\", 1);
              }
              public static staticMethods = {};
          }
      }
      export namespace codegen.Test {
          export class Foo extends il2js.NativeStruct {
              public static [TypeName] = \\"codegen.Test.Foo\\";
              static get size() { return 8 + il2js.NativeStruct.sizeof(codegen.Test.Bar); }
              public static fieldNames: string[] = [\\"bar\\"];
              public get bar(): codegen.Test.Bar {
                  return this.readField(8, codegen.Test.Bar, 1);
              }
              public static staticMethods = {
                  \\"get_instance\\": () => new il2js.MethodInfo(1234)
              };
          }
      }",
      ]
    `);
    });
    it('with custom typelib', async () => {
        class CustomType extends core_1.il2js.NativeStruct {
        }
        CustomType.size = 0;
        CustomType.fieldNames = [];
        const writeFile = jest.fn((_path, _value) => Promise.resolve());
        const load = jest.fn();
        const gasm = {
            cached: false,
            gameAssemblyDllPath: 'foo/TestGameAssembly.dll',
            globalMetadataPath: 'foo/metadata/globalMetadata.dat',
            load,
            version: '123',
            structs: {
                TypeInfoList: [
                    Types_1.mockIl2CppTypeDefinitionInfo({ TypeName: 'Foo', Namespace: 'Test' }, {
                        ImageName: 'image',
                        Fields: [
                            {
                                Type: Types_1.mockIl2CppTypeInfo({
                                    TypeName: 'CustomType',
                                    Namespace: 'Custom.Namespace',
                                    Indirection: 1,
                                }),
                                Name: 'value',
                                Offset: 0x8,
                            },
                        ],
                    }),
                ],
                TypeNameToStaticMethods: {},
            },
        };
        await Codegen_1.codegen({
            gasm,
            output: {
                entry: 'index.ts',
                outputDir: 'out',
            },
            targets: [['typescript', { rootNamespace: 'codegen' }]],
            api: { writeFile },
            types: ['@il2js/core', { from: './customTypes', types: { Custom: { Namespace: { CustomType } } } }],
        });
        expect(writeFile.mock.calls[0]).toMatchInlineSnapshot(`
      Array [
        "out\\\\index.ts",
        "import { Address, TypeName, bindTypeArgs, System, il2js } from \\"@il2js/core\\";
      import { Custom } from \\"./customTypes\\";
      export const GameAssemblyInfo = {
          assemblyName: \\"TestGameAssembly.dll\\",
          version: \\"123\\"
      };
      export namespace codegen.Test {
          export class Foo extends il2js.NativeStruct {
              public static [TypeName] = \\"codegen.Test.Foo\\";
              static get size() { return 8 + il2js.NativeStruct.sizeof(Custom.Namespace.CustomType); }
              public static fieldNames: string[] = [\\"value\\"];
              public get value(): Custom.Namespace.CustomType {
                  return this.readField(8, Custom.Namespace.CustomType, 1);
              }
              public static staticMethods = {};
          }
      }",
      ]
    `);
    });
    it('inject with custom type override', async () => {
        class CustomType extends core_1.il2js.NativeStruct {
        }
        CustomType.size = 0;
        CustomType.fieldNames = [];
        const writeFile = jest.fn((_path, _value) => Promise.resolve());
        const load = jest.fn();
        const gasm = {
            cached: false,
            gameAssemblyDllPath: 'foo/TestGameAssembly.dll',
            globalMetadataPath: 'foo/metadata/globalMetadata.dat',
            load,
            version: '123',
            structs: {
                TypeInfoList: [
                    Types_1.mockIl2CppTypeDefinitionInfo({ TypeName: 'Bar', Namespace: 'Test' }, {
                        ImageName: 'image',
                        Fields: [],
                    }),
                    Types_1.mockIl2CppTypeDefinitionInfo({ TypeName: 'Foo', Namespace: 'Test' }, {
                        ImageName: 'image',
                        Fields: [
                            {
                                Type: Types_1.mockIl2CppTypeInfo({
                                    TypeName: 'Bar',
                                    Namespace: 'Test',
                                    Indirection: 1,
                                }),
                                Name: 'value',
                                Offset: 0x8,
                            },
                        ],
                    }),
                ],
                TypeNameToStaticMethods: {},
            },
        };
        await Codegen_1.codegen({
            gasm,
            output: {
                entry: 'index.ts',
                outputDir: 'out',
            },
            targets: [
                [
                    'typescript',
                    {
                        rootNamespace: 'codegen',
                        visitors: {
                            class(type) {
                                if (type.Type.TypeName === 'Bar' && type.Type.Namespace === 'Test') {
                                    return undefined;
                                }
                                return type;
                            },
                            typeRef(type) {
                                if (type.TypeName === 'Bar' && type.Namespace === 'Test') {
                                    type.Namespace = 'Injected';
                                }
                                return type;
                            },
                        },
                    },
                ],
            ],
            api: { writeFile },
            types: ['@il2js/core', { from: './customTypes', types: { Injected: { Bar: CustomType } } }],
        });
        expect(writeFile.mock.calls[0]).toMatchInlineSnapshot(`
      Array [
        "out\\\\index.ts",
        "import { Address, TypeName, bindTypeArgs, System, il2js } from \\"@il2js/core\\";
      import { Injected } from \\"./customTypes\\";
      export const GameAssemblyInfo = {
          assemblyName: \\"TestGameAssembly.dll\\",
          version: \\"123\\"
      };
      export namespace codegen.Test {
          export class Foo extends il2js.NativeStruct {
              public static [TypeName] = \\"codegen.Test.Foo\\";
              static get size() { return 8 + il2js.NativeStruct.sizeof(Injected.Bar); }
              public static fieldNames: string[] = [\\"value\\"];
              public get value(): Injected.Bar {
                  return this.readField(8, Injected.Bar, 1);
              }
              public static staticMethods = {};
          }
      }",
      ]
    `);
    });
});
//# sourceMappingURL=Codegen.test.js.map