/*
 * Copyright (c) 2021 Cisco Systems and/or its affiliates.
 * 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.
 */

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

// This file is the main program driver to mount the stats segment filesystem.
package main

import (
	"flag"
	"fmt"
	"log"
	"log/syslog"
	"os"
	"os/signal"
	"runtime"
	"strings"
	"syscall"

	"git.fd.io/govpp.git/adapter/statsclient"
	"git.fd.io/govpp.git/core"
	"github.com/hanwen/go-fuse/v2/fs"
)

func LogMsg(msg string) {
	fmt.Fprint(os.Stderr, msg)
	log.Print(msg)
}

func main() {
	syslogger, err := syslog.New(syslog.LOG_ERR|syslog.LOG_DAEMON, "statsfs")
	if err != nil {
		log.Fatalln(err)
	}
	log.SetOutput(syslogger)

	statsSocket := flag.String("socket", statsclient.DefaultSocketName, "Path to VPP stats socket")
	debug := flag.Bool("debug", false, "print debugging messages.")
	flag.Parse()

	if flag.NArg() < 1 {
		LogMsg(fmt.Sprintf("usage: %s MOUNTPOINT\n", os.Args[0]))
		os.Exit(2)
	}
	//Conection to the stat segment socket.
	sc := statsclient.NewStatsClient(*statsSocket)
	fmt.Println("Waiting for the VPP socket to be available. Be sure a VPP instance is running.")
	c, err := core.ConnectStats(sc)
	if err != nil {
		LogMsg(fmt.Sprintf("Failed to connect to the stats socket: %v\n", err))
		os.Exit(1)
	}
	defer c.Disconnect()
	fmt.Printf("Connected to the socket\n")
	//Creating the filesystem instance
	root, err := NewStatsFileSystem(sc)
	if err != nil {
		LogMsg(fmt.Sprintf("NewStatsFileSystem failed: %v\n", err))
		os.Exit(1)
	}

	//Mounting the filesystem.
	opts := &fs.Options{}
	opts.Debug = *debug
	opts.AllowOther = true
	server, err := fs.Mount(flag.Arg(0), root, opts)
	if err != nil {
		LogMsg(fmt.Sprintf("Mount fail: %v\n", err))
		os.Exit(1)
	}

	sigs := make(chan os.Signal)
	signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

	fmt.Printf("Successfully mounted the file system in directory: %s\n", flag.Arg(0))
	runtime.GC()

	for {
		go server.Wait()

		<-sigs
		fmt.Println("Unmounting...")
		err := server.Unmount()
		if err == nil || !strings.Contains(err.Error(), "Device or resource busy") {
			break
		}
		LogMsg(fmt.Sprintf("Unmount fail: %v\n", err))
	}
}
