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

// The following enables go generate to generate the doc.go file.
//go:generate go run $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help

package main

import (
	"fmt"
	"net"
	"net/http"
	"os"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/x/lib/cmdline"
	"v.io/x/lib/netstate"
	"v.io/x/ref/lib/signals"
	"v.io/x/ref/lib/v23cmd"
	"v.io/x/ref/lib/xrpc"
	_ "v.io/x/ref/runtime/factories/roaming"
	"v.io/x/ref/services/internal/binarylib"
)

const defaultDepth = 3

var name, rootDirFlag, httpAddr string

func main() {
	cmdBinaryD.Flags.StringVar(&name, "name", "", "Name to mount the binary repository as.")
	cmdBinaryD.Flags.StringVar(&rootDirFlag, "root-dir", "", "Root directory for the binary repository.")
	cmdBinaryD.Flags.StringVar(&httpAddr, "http", ":0", "TCP address on which the HTTP server runs.")

	cmdline.HideGlobalFlagsExcept()
	cmdline.Main(cmdBinaryD)
}

var cmdBinaryD = &cmdline.Command{
	Runner: v23cmd.RunnerFunc(runBinaryD),
	Name:   "binaryd",
	Short:  "Runs the binary daemon.",
	Long: `
Command binaryd runs the binary daemon, which implements the
v.io/v23/services/repository.Binary interface.
`,
}

// toIPPort tries to swap in the 'best' accessible IP for the host part of the
// address, if the provided address has an unspecified IP.
func toIPPort(ctx *context.T, addr string) string {
	// TODO(caprita): consider using netstate.PossibleAddresses()
	host, port, err := net.SplitHostPort(addr)
	if err != nil {
		ctx.Errorf("SplitHostPort(%v) failed: %v", addr, err)
		os.Exit(1)
	}
	ip := net.ParseIP(host)
	if ip.IsUnspecified() {
		host = "127.0.0.1"
		ips, err := netstate.GetAccessibleIPs()
		if err == nil {
			ls := v23.GetListenSpec(ctx)
			if a, err := ls.AddressChooser.ChooseAddress("tcp", ips.AsNetAddrs()); err == nil && len(a) > 0 {
				host = a[0].String()
			}
		}
	}
	return net.JoinHostPort(host, port)
}

func runBinaryD(ctx *context.T, env *cmdline.Env, args []string) error {
	rootDir, err := binarylib.SetupRootDir(rootDirFlag)
	if err != nil {
		return fmt.Errorf("SetupRootDir(%q) failed: %v", rootDirFlag, err)
	}
	ctx.Infof("Binary repository rooted at %v", rootDir)

	listener, err := net.Listen("tcp", httpAddr)
	if err != nil {
		return fmt.Errorf("Listen(%s) failed: %v", httpAddr, err)
	}
	rootURL := toIPPort(ctx, listener.Addr().String())
	state, err := binarylib.NewState(rootDir, rootURL, defaultDepth)
	if err != nil {
		return fmt.Errorf("NewState(%v, %v, %v) failed: %v", rootDir, rootURL, defaultDepth, err)
	}
	ctx.Infof("Binary repository HTTP server at: %q", rootURL)
	go func() {
		if err := http.Serve(listener, http.FileServer(binarylib.NewHTTPRoot(ctx, state))); err != nil {
			ctx.Errorf("Serve() failed: %v", err)
			os.Exit(1)
		}
	}()

	dis, err := binarylib.NewDispatcher(ctx, state)
	if err != nil {
		return fmt.Errorf("NewDispatcher() failed: %v\n", err)
	}
	server, err := xrpc.NewDispatchingServer(ctx, name, dis)
	if err != nil {
		return fmt.Errorf("NewServer() failed: %v", err)
	}
	defer server.Stop()
	epName := server.Status().Endpoints[0].Name()
	if name != "" {
		ctx.Infof("Binary repository serving at %q (%q)", name, epName)
	} else {
		ctx.Infof("Binary repository serving at %q", epName)
	}
	// Wait until shutdown.
	<-signals.ShutdownOnSignals(ctx)
	return nil
}
