// 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/common"
	"github.com/apache/skywalking-cli/commands/trace"

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

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

	"github.com/apache/skywalking-cli/commands/endpoint"
	"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
var version string // Will be initialized when building

func init() {
	log = logger.Log
}

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

	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.NewStringFlag(cli.StringFlag{
			Name:     "timezone",
			Required: false,
			Hidden:   true,
			Usage:    "the timezone of the server side",
		}),
		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{
		endpoint.Command,
		instance.Command,
		service.Command,
		metrics.Command,
		trace.Command,
		common.Command,
		dashboard.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
}
