package overlay

import (
	"encoding/json"
	"fmt"
	"net"
	"sync"

	"github.com/Microsoft/hcsshim"
	"github.com/docker/docker/pkg/system"
	"github.com/docker/libnetwork/driverapi"
	"github.com/docker/libnetwork/drivers/windows"
	"github.com/docker/libnetwork/netlabel"
	"github.com/docker/libnetwork/types"
	"github.com/sirupsen/logrus"
)

type endpointTable map[string]*endpoint

const overlayEndpointPrefix = "overlay/endpoint"

type endpoint struct {
	id             string
	nid            string
	profileID      string
	remote         bool
	mac            net.HardwareAddr
	addr           *net.IPNet
	disablegateway bool
	portMapping    []types.PortBinding // Operation port bindings
}

var (
	//Server 2016 (RS1) does not support concurrent add/delete of endpoints.  Therefore, we need
	//to use this mutex and serialize the add/delete of endpoints on RS1.
	endpointMu   sync.Mutex
	windowsBuild = system.GetOSVersion().Build
)

func validateID(nid, eid string) error {
	if nid == "" {
		return fmt.Errorf("invalid network id")
	}

	if eid == "" {
		return fmt.Errorf("invalid endpoint id")
	}

	return nil
}

func (n *network) endpoint(eid string) *endpoint {
	n.Lock()
	defer n.Unlock()

	return n.endpoints[eid]
}

func (n *network) addEndpoint(ep *endpoint) {
	n.Lock()
	n.endpoints[ep.id] = ep
	n.Unlock()
}

func (n *network) deleteEndpoint(eid string) {
	n.Lock()
	delete(n.endpoints, eid)
	n.Unlock()
}

func (n *network) removeEndpointWithAddress(addr *net.IPNet) {
	var networkEndpoint *endpoint
	n.Lock()
	for _, ep := range n.endpoints {
		if ep.addr.IP.Equal(addr.IP) {
			networkEndpoint = ep
			break
		}
	}

	if networkEndpoint != nil {
		delete(n.endpoints, networkEndpoint.id)
	}
	n.Unlock()

	if networkEndpoint != nil {
		logrus.Debugf("Removing stale endpoint from HNS")
		_, err := endpointRequest("DELETE", networkEndpoint.profileID, "")
		if err != nil {
			logrus.Debugf("Failed to delete stale overlay endpoint (%.7s) from hns", networkEndpoint.id)
		}
	}
}

func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
	epOptions map[string]interface{}) error {
	var err error
	if err = validateID(nid, eid); err != nil {
		return err
	}

	n := d.network(nid)
	if n == nil {
		return fmt.Errorf("network id %q not found", nid)
	}

	ep := n.endpoint(eid)
	if ep != nil {
		logrus.Debugf("Deleting stale endpoint %s", eid)
		n.deleteEndpoint(eid)
		_, err := endpointRequest("DELETE", ep.profileID, "")
		if err != nil {
			return err
		}
	}

	ep = &endpoint{
		id:   eid,
		nid:  n.id,
		addr: ifInfo.Address(),
		mac:  ifInfo.MacAddress(),
	}

	if ep.addr == nil {
		return fmt.Errorf("create endpoint was not passed interface IP address")
	}

	s := n.getSubnetforIP(ep.addr)
	if s == nil {
		return fmt.Errorf("no matching subnet for IP %q in network %q", ep.addr, nid)
	}

	// Todo: Add port bindings and qos policies here

	hnsEndpoint := &hcsshim.HNSEndpoint{
		Name:              eid,
		VirtualNetwork:    n.hnsID,
		IPAddress:         ep.addr.IP,
		EnableInternalDNS: true,
		GatewayAddress:    s.gwIP.String(),
	}

	if ep.mac != nil {
		hnsEndpoint.MacAddress = ep.mac.String()
	}

	paPolicy, err := json.Marshal(hcsshim.PaPolicy{
		Type: "PA",
		PA:   n.providerAddress,
	})

	if err != nil {
		return err
	}

	hnsEndpoint.Policies = append(hnsEndpoint.Policies, paPolicy)

	if system.GetOSVersion().Build > 16236 {
		natPolicy, err := json.Marshal(hcsshim.PaPolicy{
			Type: "OutBoundNAT",
		})

		if err != nil {
			return err
		}

		hnsEndpoint.Policies = append(hnsEndpoint.Policies, natPolicy)

		epConnectivity, err := windows.ParseEndpointConnectivity(epOptions)
		if err != nil {
			return err
		}

		pbPolicy, err := windows.ConvertPortBindings(epConnectivity.PortBindings)
		if err != nil {
			return err
		}
		hnsEndpoint.Policies = append(hnsEndpoint.Policies, pbPolicy...)

		ep.disablegateway = true
	}

	configurationb, err := json.Marshal(hnsEndpoint)
	if err != nil {
		return err
	}

	hnsresponse, err := endpointRequest("POST", "", string(configurationb))
	if err != nil {
		return err
	}

	ep.profileID = hnsresponse.Id

	if ep.mac == nil {
		ep.mac, err = net.ParseMAC(hnsresponse.MacAddress)
		if err != nil {
			return err
		}

		if err := ifInfo.SetMacAddress(ep.mac); err != nil {
			return err
		}
	}

	ep.portMapping, err = windows.ParsePortBindingPolicies(hnsresponse.Policies)
	if err != nil {
		endpointRequest("DELETE", hnsresponse.Id, "")
		return err
	}

	n.addEndpoint(ep)

	return nil
}

func (d *driver) DeleteEndpoint(nid, eid string) error {
	if err := validateID(nid, eid); err != nil {
		return err
	}

	n := d.network(nid)
	if n == nil {
		return fmt.Errorf("network id %q not found", nid)
	}

	ep := n.endpoint(eid)
	if ep == nil {
		return fmt.Errorf("endpoint id %q not found", eid)
	}

	n.deleteEndpoint(eid)

	_, err := endpointRequest("DELETE", ep.profileID, "")
	if err != nil {
		return err
	}

	return nil
}

func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, error) {
	if err := validateID(nid, eid); err != nil {
		return nil, err
	}

	n := d.network(nid)
	if n == nil {
		return nil, fmt.Errorf("network id %q not found", nid)
	}

	ep := n.endpoint(eid)
	if ep == nil {
		return nil, fmt.Errorf("endpoint id %q not found", eid)
	}

	data := make(map[string]interface{}, 1)
	data["hnsid"] = ep.profileID
	data["AllowUnqualifiedDNSQuery"] = true

	if ep.portMapping != nil {
		// Return a copy of the operational data
		pmc := make([]types.PortBinding, 0, len(ep.portMapping))
		for _, pm := range ep.portMapping {
			pmc = append(pmc, pm.GetCopy())
		}
		data[netlabel.PortMap] = pmc
	}

	return data, nil
}

func endpointRequest(method, path, request string) (*hcsshim.HNSEndpoint, error) {
	if windowsBuild == 14393 {
		endpointMu.Lock()
	}
	hnsresponse, err := hcsshim.HNSEndpointRequest(method, path, request)
	if windowsBuild == 14393 {
		endpointMu.Unlock()
	}
	return hnsresponse, err
}
