import { App, Stack } from 'aws-cdk-lib';
import { Environment } from '../shared/environment';
import { createApp } from './app';

describe('App', () => {
  describe('Given the default CDK environment variables extracted from the AWS profile,', () => {
    let app: App;

    beforeEach(() => {
      process.env['CDK_DEFAULT_ACCOUNT'] = '012345678901';
      process.env['CDK_DEFAULT_REGION'] = 'us-east-1';
    <% environments.forEach((environment) => { %>
      delete process.env['CDK_<%= environment.toUpperCase() %>_ACCOUNT'];
      delete process.env['CDK_<%= environment.toUpperCase() %>_REGION'];
    <% }); %>
    });

    test('an app should be created with all environments.', () => {
      app = createApp();

      const children = app.node.children;

      expect(children.map((construct) => construct.node.id)).toEqual([
      <% environments.forEach((environment) => { %>
        Environment.<%= environment %>,
      <% }); %>
      ]);
    });

    test('an app should be created with the correct environment accounts and regions.', () => {
      app = createApp();

      const children = app.node.children;

      expect(
        children.map((construct) => {
          const stack = construct.node.children[0] as Stack;

          return {
            id: construct.node.id,
            account: stack.account,
            region: stack.region,
          };
        }),
      ).toEqual([
      <% environments.forEach((environment, index) => { %>
        { id: Environment.<%= environment %>, account: '012345678901', region: 'us-east-1' },
      <% }); %>
      ]);
    });
  });

  describe('Given a set of app-specific environment variables,', () => {
    let app: App;

    beforeEach(() => {
    <% environments.forEach((environment, index) => { %>
      process.env['CDK_<%= environment.toUpperCase() %>_ACCOUNT'] = '12345678901<%= index %>';
      process.env['CDK_<%= environment.toUpperCase() %>_REGION'] = 'eu-west-<%= index + 1 %>';
    <% }); %>

      delete process.env['CDK_DEFAULT_ACCOUNT'];
      delete process.env['CDK_DEFAULT_REGION'];
    });

    test('an app should be created with all environments.', () => {
      app = createApp();

      const children = app.node.children;

      expect(children.map((construct) => construct.node.id)).toEqual([
      <% environments.forEach((environment) => { %>
        Environment.<%= environment %>,
      <% }); %>
      ]);
    });

    test('an app should be created with the correct environment accounts and regions.', () => {
      app = createApp();

      const children = app.node.children;

      expect(
        children.map((construct) => {
          const stack = construct.node.children[0] as Stack;

          return {
            id: construct.node.id,
            account: stack.account,
            region: stack.region,
          };
        }),
      ).toEqual([
      <% environments.forEach((environment, index) => { %>
        { id: Environment.<%= environment %>, account: '12345678901<%= index %>', region: 'eu-west-<%= index + 1 %>' },
      <% }); %>
      ]);
    });
  <% environments.forEach((environment) => { %>
    test('should throw an error if the CDK_<%= environment.toUpperCase() %>_ACCOUNT variable is missing during the creation.', () => {
      delete process.env['CDK_<%= environment.toUpperCase() %>_ACCOUNT'];
      expect(() => createApp()).toThrow(Error);
    });

    test('should throw an error if the CDK_<%= environment.toUpperCase() %>_REGION variable is missing during the creation.', () => {
      delete process.env['CDK_<%= environment.toUpperCase() %>_REGION'];
      expect(() => createApp()).toThrow(Error);
    });
  <% }); %>
  });
});
