/*
 * Copyright (C) 2023 Amazon.com, Inc. or its affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * CDK Nag for Opensearch Domain
 *
 * @group nag/opensearch-domain
 */

import { App, Aspects, Stack } from 'aws-cdk-lib';
import { Annotations, Match } from 'aws-cdk-lib/assertions';
import { AwsSolutionsChecks, NagSuppressions } from 'cdk-nag';
import { OpenSearchDomain } from '../../src'
import { SubnetType, Vpc } from "aws-cdk-lib/aws-ec2";

const mockApp = new App();
const mockStack = new Stack(mockApp, 'NagStack');

// Instantiate Construct
new OpenSearchDomain(mockStack, 'opensearch', {
  vpc: new Vpc(mockStack, 'vpc', {subnetConfiguration: [{
      cidrMask: 24,
      name: 'ingress',
      subnetType: SubnetType.PUBLIC,
    },
    {
      cidrMask: 24,
      name: 'application',
      subnetType: SubnetType.PRIVATE_WITH_EGRESS,
    },
    {
      cidrMask: 28,
      name: 'rds',
      subnetType: SubnetType.PRIVATE_ISOLATED,
    }]})
})

Aspects.of(mockStack).add(new AwsSolutionsChecks({ verbose: true }));

NagSuppressions.addResourceSuppressionsByPath(
    mockStack,
    '/NagStack/vpc/Resource',
    [{ id: 'AwsSolutions-VPC7', reason: 'VPC is provided by the customer, not part of the construct' }],
);

NagSuppressions.addResourceSuppressionsByPath(
    mockStack,
    '/NagStack/opensearch/Userpool/Resource',
    [{ id: 'AwsSolutions-COG3', reason: 'AdvancedSecurityMode incurs additional costs to the user. They can provide their own user pool if they want to enable it.' }],
);

NagSuppressions.addStackSuppressions(mockStack, [
  { id: 'AwsSolutions-IAM4', reason: 'Using standard managed policies' }
]);


NagSuppressions.addResourceSuppressionsByPath(
    mockStack,
    '/NagStack/opensearch/Domain/Resource',
    [
        { id: 'AwsSolutions-OS3', reason: 'Customer can enable this with construct parameters, not by default' },
        { id: 'AwsSolutions-OS4', reason: 'Customer can enable this with construct parameters, not by default (additional costs)' },
        { id: 'AwsSolutions-OS7', reason: 'Customer can enable this with construct parameters, not by default (additional costs)' },
        { id: 'AwsSolutions-OS9', reason: 'Customer can enable this with construct parameters, not by default' }
    ],
);

NagSuppressions.addResourceSuppressionsByPath(
    mockStack,
    '/NagStack/AWS679f53fac002430cb0da5b7982bd2287/Resource',
    [
      { id: 'AwsSolutions-L1', reason: 'Function generated by a CDK construct' },
    ],
);

NagSuppressions.addStackSuppressions(mockStack, [
  { id: 'AwsSolutions-IAM4', reason: 'Using standard managed policies' }
]);

describe('CDK Nag', () => {

  test('No unsuppressed Errors', () => {
    const errors = Annotations
      .fromStack(mockStack)
      .findError('*', Match.stringLikeRegexp('AwsSolutions-.*'));
    if (errors && errors.length > 0) {
      console.log(errors);
    }
    expect(errors).toHaveLength(0);
  });

});
