package awsutil

import (
	"testing"

	"github.com/stretchr/testify/mock"
	"github.com/stretchr/testify/require"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/ec2"
	"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
)

type MockEC2 struct {
	mock.Mock
	ec2iface.EC2API
}

func (c *MockEC2) DescribeInstances(input *ec2.DescribeInstancesInput) (*ec2.DescribeInstancesOutput, error) {
	args := c.Called(input)
	return args.Get(0).(*ec2.DescribeInstancesOutput), args.Error(1)
}

type MockMetadata struct {
	mock.Mock
	Metadata
}

func (c *MockMetadata) GetMetadata(path string) (string, error) {
	args := c.Called(path)
	return args.String(0), args.Error(1)
}

func TestLocalInstanceInstanceFound(t *testing.T) {
	ec2Client := &MockEC2{}
	metadata := &MockMetadata{}

	metadata.On("GetMetadata", "instance-id").Return("test-instance", nil)
	ec2Client.On("DescribeInstances", &ec2.DescribeInstancesInput{
		InstanceIds: []*string{
			aws.String("test-instance"),
		},
	}).Return(&ec2.DescribeInstancesOutput{
		Reservations: []*ec2.Reservation{
			&ec2.Reservation{
				Instances: []*ec2.Instance{
					&ec2.Instance{
						InstanceId: aws.String("test-instance"),
					},
				},
			},
		},
	}, nil)

	instance, err := FetchLocalInstance(ec2Client, metadata)
	require.Nil(t, err)
	require.NotNil(t, instance)
	require.Equal(t, "test-instance", *instance.InstanceId)
	ec2Client.AssertExpectations(t)
	metadata.AssertExpectations(t)
}

func TestLocalInstanceNoInstanceFound(t *testing.T) {
	ec2Client := &MockEC2{}
	metadata := &MockMetadata{}

	metadata.On("GetMetadata", "instance-id").Return("test-instance", nil)
	ec2Client.On("DescribeInstances", &ec2.DescribeInstancesInput{
		InstanceIds: []*string{
			aws.String("test-instance"),
		},
	}).Return(&ec2.DescribeInstancesOutput{
		Reservations: []*ec2.Reservation{
			&ec2.Reservation{},
		},
	}, nil)

	instance, err := FetchLocalInstance(ec2Client, metadata)
	require.NotNil(t, err)
	require.Nil(t, instance)
	require.Equal(t, "Couldn't find the local instance using the local metadata.  Is something wrong?", err.Error())
	ec2Client.AssertExpectations(t)
	metadata.AssertExpectations(t)
}
