// Copyright 2019 CUE Authors
//
// 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.

package net

import (
	"fmt"
	"net"
	"strconv"
	"unicode/utf8"

	"cuelang.org/go/cue"
	"golang.org/x/net/idna"
)

var idnaProfile = idna.New(
	idna.ValidateLabels(true),
	idna.VerifyDNSLength(true),
	idna.StrictDomainName(true),
)

// SplitHostPort splits a network address of the form "host:port",
// "host%zone:port", "[host]:port" or "[host%zone]:port" into host or host%zone
// and port.
//
// A literal IPv6 address in hostport must be enclosed in square brackets, as in
// "[::1]:80", "[::1%lo0]:80".
func SplitHostPort(s string) (hostport []string, err error) {
	host, port, err := net.SplitHostPort(s)
	if err != nil {
		return nil, err
	}
	return []string{host, port}, nil
}

// JoinHostPort combines host and port into a network address of the
// form "host:port". If host contains a colon, as found in literal
// IPv6 addresses, then JoinHostPort returns "[host]:port".
//
// See func Dial for a description of the host and port parameters.
func JoinHostPort(host, port cue.Value) (string, error) {
	var err error
	hostStr := ""
	switch host.Kind() {
	case cue.ListKind:
		ipdata := netGetIP(host)
		if len(ipdata) != 4 && len(ipdata) != 16 {
			err = fmt.Errorf("invalid host %q", host)
		}
		hostStr = ipdata.String()
	case cue.BytesKind:
		var b []byte
		b, err = host.Bytes()
		hostStr = string(b)
	default:
		hostStr, err = host.String()
	}
	if err != nil {
		return "", err
	}

	portStr := ""
	switch port.Kind() {
	case cue.StringKind:
		portStr, err = port.String()
	case cue.BytesKind:
		var b []byte
		b, err = port.Bytes()
		portStr = string(b)
	default:
		var i int64
		i, err = port.Int64()
		portStr = strconv.Itoa(int(i))
	}
	if err != nil {
		return "", err
	}

	return net.JoinHostPort(hostStr, portStr), nil
}

// FQDN reports whether is is a valid fully qualified domain name.
//
// FQDN allows only ASCII characters as prescribed by RFC 1034 (A-Z, a-z, 0-9
// and the hyphen).
func FQDN(s string) bool {
	for i := 0; i < len(s); i++ {
		if s[i] >= utf8.RuneSelf {
			return false
		}
	}
	_, err := idnaProfile.ToASCII(s)
	return err == nil
}
