//
// goamz - Go packages to interact with the Amazon Web Services.
//
//   https://wiki.ubuntu.com/goamz
//
// Copyright (c) 2015 Canonical Ltd.
//

package ec2test_test

import (
	. "gopkg.in/check.v1"

	"gopkg.in/amz.v3/ec2"
)

func (s *S) TestAddRouteTable(c *C) {
	added, err := s.srv.AddRouteTable(ec2.RouteTable{})
	c.Assert(err, ErrorMatches, "missing VPC id")
	c.Assert(added, DeepEquals, ec2.RouteTable{})

	added, err = s.srv.AddRouteTable(ec2.RouteTable{
		VPCId: "missing",
	})
	c.Assert(err, ErrorMatches, `VPC "missing" not found`)
	c.Assert(added, DeepEquals, ec2.RouteTable{})

	// Add a table with all possible fields set or some unset.
	toAdd := ec2.RouteTable{
		Id:    "should-be-ignored",
		VPCId: "vpc-0", // testing default VPC
		Associations: []ec2.RouteTableAssociation{{
			Id:       "ignored", // replaced with rtbassoc-# (next id)
			TableId:  "table-1",
			SubnetId: "subnet-1",
			IsMain:   true,
		}, {
			Id:       "", // the same as above
			TableId:  "", // replaced with the added table's Id
			SubnetId: "",
			IsMain:   false,
		}},
		Routes: []ec2.Route{{
			DestinationCIDRBlock:    "10.10.0.0/16",
			DestinationPrefixListId: "prefix",
			GatewayId:               "local",
			InstanceId:              "instId",
			InstanceOwnerId:         "ownerId",
			InterfaceId:             "ifaceId",
			Origin:                  "origin",
			State:                   "active",
			VPCPeeringConnectionId: "connId",
		}, {
			DestinationCIDRBlock:    "",
			DestinationPrefixListId: "",
			GatewayId:               "",
			InstanceId:              "",
			InstanceOwnerId:         "",
			InterfaceId:             "",
			Origin:                  "",
			State:                   "",
			VPCPeeringConnectionId: "",
		}, {
			DestinationCIDRBlock: "0.0.0.0/0",
			GatewayId:            "igw-0", // testing default VPC's IGW
			State:                "active",
		}},
		PropagatingVGWIds: []string{"foo", "bar"},
	}
	added, err = s.srv.AddRouteTable(toAdd)
	c.Assert(err, IsNil)
	c.Assert(added.Id, Matches, `^rtb-[0-9a-f]+$`)
	// Replace the autogenerated ids only, the rest is the same.
	toAdd.Id = added.Id
	toAdd.Associations[0].Id = added.Associations[0].Id
	toAdd.Associations[1].Id = added.Associations[1].Id
	toAdd.Associations[1].TableId = added.Id
	c.Assert(added, DeepEquals, toAdd)

	resp, err := s.ec2.RouteTables([]string{added.Id}, nil)
	c.Assert(err, IsNil)
	c.Assert(resp, NotNil)
	c.Assert(resp.Tables, HasLen, 1)
	c.Assert(resp.Tables[0], DeepEquals, added)
}

func (s *S) TestUpdateRouteTable(c *C) {
	err := s.srv.UpdateRouteTable(ec2.RouteTable{})
	c.Assert(err, ErrorMatches, "missing route table id")

	err = s.srv.UpdateRouteTable(ec2.RouteTable{
		Id: "missing",
	})
	c.Assert(err, ErrorMatches, `route table "missing" not found`)
	toUpdate := ec2.RouteTable{
		Id:    "rtb-0", // the testing default VPC's table.
		VPCId: "vpc-42",
		Associations: []ec2.RouteTableAssociation{{ // fully replaced
			Id:       "assoc-1",
			TableId:  "table-1",
			SubnetId: "subnet-1",
			IsMain:   true,
		}},
		Routes: []ec2.Route{{ // fully replaced
			DestinationCIDRBlock:    "10.10.0.0/16",
			DestinationPrefixListId: "prefix",
			GatewayId:               "local",
			InstanceId:              "instId",
			InstanceOwnerId:         "ownerId",
			InterfaceId:             "ifaceId",
			Origin:                  "origin",
			State:                   "active",
			VPCPeeringConnectionId: "connId",
		}},
		PropagatingVGWIds: []string{"foo", "bar"},
	}
	err = s.srv.UpdateRouteTable(toUpdate)
	c.Assert(err, IsNil)

	filter := ec2.NewFilter()
	filter.Add("vpc-id", "vpc-42")
	filter.Add("association.route-table-association-id", "assoc-1")
	resp, err := s.ec2.RouteTables(nil, filter)
	c.Assert(err, IsNil)
	c.Assert(resp, NotNil)
	c.Assert(resp.Tables, HasLen, 1)
	c.Assert(resp.Tables[0], DeepEquals, toUpdate)
}

func (s *S) TestRemoveRouteTable(c *C) {
	s.assertRouteTablesExist(c, true) // added by AddDefaultVPCAndSubnets()

	err := s.srv.RemoveRouteTable("")
	c.Assert(err, ErrorMatches, "missing route table id")

	err = s.srv.RemoveRouteTable("missing")
	c.Assert(err, ErrorMatches, `route table "missing" not found`)

	err = s.srv.RemoveRouteTable("rtb-0") // the default VPC's route table
	c.Assert(err, IsNil)

	// There should be no more.
	s.assertRouteTablesExist(c, false)
}

func (s *S) assertRouteTablesExist(c *C, mustExist bool) {
	resp, err := s.ec2.RouteTables(nil, nil)
	c.Assert(err, IsNil)
	if !mustExist {
		c.Assert(resp.Tables, HasLen, 0)
	} else {
		c.Assert(resp.Tables, Not(HasLen), 0)
	}
}
