// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package netstack

import (
	"fmt"
	"net"
	"syscall/zx/fidl"

	"syslog"

	"netstack/dns"

	fidlnet "fidl/fuchsia/net"

	"gvisor.dev/gvisor/pkg/tcpip"
)

type nameLookupImpl struct {
	dnsClient *dns.Client
}

var _ fidlnet.NameLookupWithCtx = (*nameLookupImpl)(nil)

func (sp *nameLookupImpl) LookupIp(_ fidl.Context, hostname string, options fidlnet.LookupIpOptions) (fidlnet.NameLookupLookupIpResult, error) {
	var result fidlnet.NameLookupLookupIpResult
	var response fidlnet.NameLookupLookupIpResponse

	var ips []tcpip.Address

	if hostname == "localhost" {
		ips = []tcpip.Address{
			ipv4Loopback,
			ipv6Loopback,
		}
	} else {
		var err error
		ips, err = sp.dnsClient.LookupIP(hostname)
		if err != nil {
			syslog.VLogTf(syslog.DebugVerbosity, "DNS", "lookup failed with internal error: %s", err)
			result.SetErr(fidlnet.LookupErrorInternalError)
			return result, nil
		}
		if len(ips) == 0 {
			result.SetErr(fidlnet.LookupErrorNotFound)
			return result, nil
		}
	}

	for _, ip := range ips {
		// TODO(wesleyac): Consider handling IPv4-mapped addresses as IPv4 addresses
		if ip4 := ip.To4(); ip4 != "" && (options&fidlnet.LookupIpOptionsV4Addrs) != 0 {
			var addr fidlnet.Ipv4Address
			copy(addr.Addr[:], ip4)
			response.Addr.Ipv4Addrs = append(response.Addr.Ipv4Addrs, addr)
		} else if options&fidlnet.LookupIpOptionsV6Addrs != 0 {
			var addr fidlnet.Ipv6Address
			copy(addr.Addr[:], ip)
			response.Addr.Ipv6Addrs = append(response.Addr.Ipv6Addrs, addr)
		}
	}

	result.SetResponse(response)
	return result, nil
}

// This only supports localhost right now, since the netstack DNS client doesn't support reverse DNS.
func (sp *nameLookupImpl) LookupHostname(_ fidl.Context, addr fidlnet.IpAddress) (fidlnet.NameLookupLookupHostnameResult, error) {
	var result fidlnet.NameLookupLookupHostnameResult
	switch typ := addr.Which(); typ {
	case fidlnet.IpAddressIpv4:
		if net.IP(addr.Ipv4.Addr[:]).IsLoopback() {
			result.SetResponse(fidlnet.NameLookupLookupHostnameResponse{Hostname: "localhost"})
			return result, nil
		}
	case fidlnet.IpAddressIpv6:
		if net.IP(addr.Ipv6.Addr[:]).IsLoopback() {
			result.SetResponse(fidlnet.NameLookupLookupHostnameResponse{Hostname: "localhost"})
			return result, nil
		}
	default:
		panic(fmt.Sprintf("unknown address type: %v", typ))
	}
	result.SetErr(fidlnet.LookupErrorNotFound)
	return result, nil
}
