/*
Licensed to the 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.
The 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 cmd

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"text/template"

	"github.com/apache/camel-k/deploy"
	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
	"github.com/spf13/cobra"
)

func newCmdInit(rootCmdOptions *RootCmdOptions) (*cobra.Command, *initCmdOptions) {
	options := initCmdOptions{
		RootCmdOptions: rootCmdOptions,
	}
	cmd := cobra.Command{
		Use:     "init",
		Short:   "Initialize empty Camel K files",
		Long:    `Initialize empty Camel K integrations and other resources.`,
		PreRunE: decode(&options),
		RunE: func(cmd *cobra.Command, args []string) error {
			if err := options.validate(cmd, args); err != nil {
				return err
			}
			if err := options.init(cmd, args); err != nil {
				return err
			}
			return nil
		},
	}

	return &cmd, &options
}

type initCmdOptions struct {
	*RootCmdOptions
}

func (o *initCmdOptions) validate(_ *cobra.Command, args []string) error {
	if len(args) != 1 {
		return fmt.Errorf("init expects exactly 1 argument, received %d", len(args))
	}

	fileName := args[0]
	if o.extractLanguage(fileName) == nil {
		return fmt.Errorf("unsupported file type: %s", fileName)
	}

	return nil
}

func (o *initCmdOptions) init(_ *cobra.Command, args []string) error {
	fileName := args[0]
	language := o.extractLanguage(fileName)
	return o.writeFromTemplate(*language, fileName)
}

func (o *initCmdOptions) writeFromTemplate(language v1.Language, fileName string) error {
	simpleName := filepath.Base(fileName)
	if idx := strings.Index(simpleName, "."); idx >= 0 {
		simpleName = simpleName[:idx]
	}

	type TemplateParameters struct {
		Name string
	}
	params := TemplateParameters{
		Name: simpleName,
	}
	rawData := deploy.ResourceAsString(fmt.Sprintf("/templates/%s.tmpl", language))
	if rawData == "" {
		return fmt.Errorf("cannot find template for language %s", string(language))
	}
	tmpl, err := template.New(string(language)).Parse(rawData)
	if err != nil {
		return err
	}
	out, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0777)
	if err != nil {
		return err
	}
	defer out.Close()

	return tmpl.Execute(out, params)
}

func (o *initCmdOptions) extractLanguage(fileName string) *v1.Language {
	for _, l := range v1.Languages {
		if strings.HasSuffix(fileName, fmt.Sprintf(".%s", string(l))) {
			return &l
		}
	}
	return nil
}
