// Licensed to Apache Software Foundation (ASF) under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Apache Software Foundation (ASF) licenses this file to you 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 main

import (
	"io/ioutil"
	"os"

	"github.com/apache/skywalking-cli/commands/endpoint"
	linearMetrics "github.com/apache/skywalking-cli/commands/metrics/linear"
	singleMetrics "github.com/apache/skywalking-cli/commands/metrics/single"

	"github.com/apache/skywalking-cli/commands/instance"

	"github.com/sirupsen/logrus"
	"github.com/urfave/cli"
	"github.com/urfave/cli/altsrc"

	"github.com/apache/skywalking-cli/commands/interceptor"
	"github.com/apache/skywalking-cli/commands/service"
	"github.com/apache/skywalking-cli/logger"
	"github.com/apache/skywalking-cli/util"
)

var log *logrus.Logger

func init() {
	log = logger.Log
}

func main() {
	app := cli.NewApp()
	app.Usage = "The CLI (Command Line Interface) for Apache SkyWalking."
	app.Version = "0.1.0"

	flags := []cli.Flag{
		altsrc.NewStringFlag(cli.StringFlag{
			Name:  "config",
			Value: "~/.skywalking.yml",
			Usage: "load configuration `FILE`",
		}),
		altsrc.NewStringFlag(cli.StringFlag{
			Name:     "base-url",
			Required: false,
			Usage:    "base `url` of the OAP backend graphql",
			Value:    "http://127.0.0.1:12800/graphql",
		}),
		altsrc.NewBoolFlag(cli.BoolFlag{
			Name:     "debug",
			Required: false,
			Usage:    "enable debug mode, will print more detailed logs",
		}),
		altsrc.NewStringFlag(cli.StringFlag{
			Name:     "display",
			Required: false,
			Usage:    "display `style` of the result, supported styles are: json, yaml, table",
			Value:    "json",
		}),
	}

	app.Commands = []cli.Command{
		service.Command,
		instance.Command,
		linearMetrics.Command,
		singleMetrics.Command,
		endpoint.Command,
	}

	app.Before = interceptor.BeforeChain([]cli.BeforeFunc{
		setUpCommandLineContext,
		expandConfigFile,
		tryConfigFile(flags),
	})

	app.Flags = flags

	if err := app.Run(os.Args); err != nil {
		log.Fatalln(err)
	}
}

func expandConfigFile(c *cli.Context) error {
	return c.Set("config", util.ExpandFilePath(c.String("config")))
}

func tryConfigFile(flags []cli.Flag) cli.BeforeFunc {
	return func(c *cli.Context) error {
		configFile := c.String("config")
		if bytes, err := ioutil.ReadFile(configFile); err == nil {
			log.Debug("Using configurations:\n", string(bytes))

			err = altsrc.InitInputSourceWithContext(flags, altsrc.NewYamlSourceFromFlagFunc("config"))(c)
			if err != nil {
				return err
			}
		} else if os.IsNotExist(err) {
			log.Debugf("open %s no such file, skip loading configuration file\n", c.GlobalString("config"))
		} else {
			return err
		}

		return nil
	}
}

func setUpCommandLineContext(c *cli.Context) error {
	if c.Bool("debug") {
		log.SetLevel(logrus.DebugLevel)
		log.Debugln("Debug mode is enabled")
	}

	return nil
}
