package utils

import (
	"fmt"
	"net/url"
	"os"
	"strings"

	"github.com/pkg/errors"
)

// Fail prints out the error struct if STEPDEBUG is true otherwise it just
// prints out the error message. Finally, it exits with an error code of 1.
func Fail(err error) {
	if err != nil {
		if os.Getenv("STEPDEBUG") == "1" {
			fmt.Fprintf(os.Stderr, "%+v\n", err)
		} else {
			fmt.Fprintln(os.Stderr, err)
		}
		os.Exit(1)
	}
}

// CompleteURL parses and validates the given URL. It supports general
// URLs like https://ca.smallstep.com[:port][/path], and incomplete URLs like
// ca.smallstep.com[:port][/path].
func CompleteURL(rawurl string) (string, error) {
	u, err := url.Parse(rawurl)
	if err != nil {
		return "", errors.Wrapf(err, "error parsing url '%s'", rawurl)
	}

	// URLs are generally parsed as:
	// [scheme:][//[userinfo@]host][/]path[?query][#fragment]
	// But URLs that do not start with a slash after the scheme are interpreted as
	// scheme:opaque[?query][#fragment]
	if u.Opaque == "" {
		if u.Scheme == "" {
			u.Scheme = "https"
		}
		if u.Host == "" {
			// rawurl looks like ca.smallstep.com or ca.smallstep.com/1.0/sign
			if u.Path != "" {
				parts := strings.SplitN(u.Path, "/", 2)
				u.Host = parts[0]
				if len(parts) == 2 {
					u.Path = parts[1]
				} else {
					u.Path = ""
				}
				return CompleteURL(u.String())
			}
			return "", errors.Errorf("error parsing url '%s'", rawurl)
		}
		return u.String(), nil
	}
	// scheme:opaque[?query][#fragment]
	// rawurl looks like ca.smallstep.com:443 or ca.smallstep.com:443/1.0/sign
	return CompleteURL("https://" + rawurl)
}
