// Copyright Istio Authors
//
// 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.

package main

import (
	"flag"
	"fmt"
	"io"
	"log"
	"os"
)

import (
	"github.com/hashicorp/go-multierror"
)

import (
	"github.com/apache/dubbo-go-pixiu/pkg/test/framework/components/cluster"
	"github.com/apache/dubbo-go-pixiu/pkg/test/framework/components/echo"
	"github.com/apache/dubbo-go-pixiu/pkg/test/framework/components/echo/common/ports"
	"github.com/apache/dubbo-go-pixiu/pkg/test/framework/components/echo/kube"
	"github.com/apache/dubbo-go-pixiu/pkg/test/framework/config"
	"github.com/apache/dubbo-go-pixiu/pkg/test/framework/resource"
	"github.com/apache/dubbo-go-pixiu/pkg/test/util/yml"
)

var (
	outputPath string
	dirOutput  bool
)

func init() {
	flag.StringVar(&outputPath, "out", "", "If specified, all generated output will be written to this file.")
	flag.BoolVar(&dirOutput, "dir", false, "If true, all generated output will be written to separate files per-config, in a directory named by -out.")
}

func main() {
	if !config.Parsed() {
		config.Parse()
	}
	if flag.NArg() < 1 {
		flag.Usage()
		os.Exit(1)
	}
	generate(flag.Args()[0], outputPath, dirOutput, os.Stdout)
}

func generate(input, output string, outputDir bool, outstream io.StringWriter) {
	if !config.Parsed() {
		// for tests
		config.Parse()
	}

	gen := newGenerator()
	if err := gen.load(input); err != nil {
		log.Fatalf("failed loading %s: %v", input, err)
	}
	if err := gen.generate(); err != nil {
		log.Fatalf("failed generating manifests: %v", err)
	}

	var err error
	if output != "" {
		err = gen.writeOutputFile(output, outputDir)
	} else {
		_, err = outstream.WriteString(gen.joinManifests())
	}
	if err != nil {
		log.Fatalf("failed writing output: %v", err)
	}
}

type generator struct {
	// settings
	settings *resource.Settings

	// internal
	configs   []echo.Config
	manifests map[string]string
}

func newGenerator() generator {
	// we read resource package settings to respsect --istio.test.versions
	settings, err := resource.SettingsFromCommandLine("echogen")
	if err != nil {
		log.Fatalf("failed reading test framework settings: %v", err)
	}

	return generator{
		settings: settings,
	}
}

func (g *generator) load(input string) error {
	// deserialize
	bytes, err := os.ReadFile(input)
	if err != nil {
		return fmt.Errorf("failed reading file: %v", err)
	}
	g.configs, err = echo.ParseConfigs(bytes)
	if err != nil {
		return fmt.Errorf("failed parsing file: %v", err)
	}
	// fill in defaults
	c := cluster.NewFake("fake", "1", "20")
	for i, cfg := range g.configs {
		if len(cfg.Ports) == 0 {
			cfg.Ports = ports.All()
		}
		cfg.Cluster = c
		if err := cfg.FillDefaults(nil); err != nil {
			return fmt.Errorf("failed filling defaults for %s: %v", cfg.ClusterLocalFQDN(), err)
		}
		g.configs[i] = cfg
	}
	return nil
}

func (g *generator) generate() error {
	outputByFQDN := map[string]string{}
	var errs error
	for _, cfg := range g.configs {
		id := cfg.ClusterLocalFQDN()
		// generate
		svc, err := kube.GenerateService(cfg)
		if err != nil {
			errs = multierror.Append(errs, fmt.Errorf("failed generating service for %s: %v", id, err))
			continue
		}
		deployment, err := kube.GenerateDeployment(cfg, g.settings)
		if err != nil {
			errs = multierror.Append(errs, fmt.Errorf("failed generating deployment for %s: %v", id, err))
			continue
		}
		outputByFQDN[id] = yml.JoinString(svc, deployment)
		// add namespace if specified
		if cfg.Namespace.Name() != "" {
			var err error
			outputByFQDN[id], err = yml.ApplyNamespace(outputByFQDN[id], cfg.Namespace.Name())
			if err != nil {
				return fmt.Errorf("error applying namespace to %s: %v", id, err)
			}
		}

	}
	g.manifests = outputByFQDN
	return errs
}

func (g *generator) joinManifests() string {
	var m []string
	for _, yaml := range g.manifests {
		m = append(m, yaml)
	}
	return yml.JoinString(m...)
}

func (g *generator) writeOutputFile(path string, dir bool) error {
	if dir {
		// multi file
		if err := os.Mkdir(path, 0o644); err != nil {
			return fmt.Errorf("failed creating directory %s: %v", path, err)
		}
		for id, yaml := range g.manifests {
			fname := id + ".yaml"
			if err := os.WriteFile(fname, []byte(yaml), 0o644); err != nil {
				return fmt.Errorf("failed writing %s: %v", fname, err)
			}
		}
	} else if err := os.WriteFile(path, []byte(g.joinManifests()), 0o644); err != nil {
		return fmt.Errorf("failed writing %s: %v", path, err)
	}
	return nil
}
