// Copyright 2020 The Monogon Project Authors.
//
// SPDX-License-Identifier: Apache-2.0
//
// 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 watchers

import (
	"encoding/xml"
	"fmt"
	"io/ioutil"
	"os"
	"path"
)

const (
	fileWatchersPath = ".ijwb/.idea/watcherTasks.xml"
	templatePath     = "intellij/localconfig/data/watcherTasks.xml"
)

type config struct {
	XMLName   xml.Name  `xml:"project"`
	Version   string    `xml:"version,attr"`
	Component component `xml:"component"`
}

type component struct {
	Name        string       `xml:"name,attr"`
	TaskOptions []taskOption `xml:"TaskOptions"`
}

type taskOption struct {
	IsEnabled string `xml:"isEnabled,attr"`
	Option    []struct {
		Name  string `xml:"name,attr"`
		Value string `xml:"value,attr,omitempty"`
		Data  string `xml:",innerxml"`
	} `xml:"option"`
	Envs struct {
		Env []struct {
			Name  string `xml:"name,attr"`
			Value string `xml:"value,attr"`
		} `xml:"env"`
	} `xml:"envs"`
}

func buildConfig(options []taskOption) *config {
	return &config{
		XMLName: xml.Name{Local: "project"},
		Version: "4",
		Component: component{
			Name:        "ProjectTasksOptions",
			TaskOptions: options,
		},
	}
}

func readConfig(filename string) (cfg *config, err error) {
	b, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, fmt.Errorf("failed reading file: %w", err)
	}

	err = xml.Unmarshal(b, &cfg)
	if err != nil {
		return nil, fmt.Errorf("failed deserializing XML: %w", err)
	}

	return
}

func (cfg *config) atomicWriteFile(filename string) error {
	b, err := xml.MarshalIndent(cfg, "", "  ")
	if err != nil {
		return fmt.Errorf("failed to serialize: %w", err)
	}

	// Atomic write is needed, IntelliJ has inotify watches on its config and reloads (but not applies) instantly.
	tmpPath := filename + ".tmp"
	defer os.Remove(tmpPath)
	if err := ioutil.WriteFile(tmpPath, []byte(xml.Header+string(b)), 0664); err != nil {
		return fmt.Errorf("failed to write: %w", err)
	}
	if err := os.Rename(tmpPath, filename); err != nil {
		return fmt.Errorf("failed to rename: %w", err)
	}

	return nil
}

// RewriteConfig adds our watchers to projectDir's watchers config, overwriting existing entries with the same name.
func RewriteConfig(projectDir string) error {
	template, err := readConfig(path.Join(projectDir, templatePath))
	if err != nil {
		return fmt.Errorf("failed reading template config: %w", err)
	}

	if template.Version != "4" {
		return fmt.Errorf("unknown template config version: %s", template.Version)
	}

	// Read existing tasks, if any.
	tasks := make(map[string]taskOption)
	cfg, err := readConfig(path.Join(projectDir, fileWatchersPath))

	switch {
	case err == nil:
		// existing config, read tasks
		if cfg.Version != "4" {
			return fmt.Errorf("unknown watchers config version: %s", cfg.Version)
		}
		for _, v := range cfg.Component.TaskOptions {
			for _, o := range v.Option {
				if o.Name == "name" {
					tasks[o.Value] = v
				}
			}
		}
	case os.IsNotExist(err):
		// no existing config - continue with empty tasks
	default:
		// error is non-nil and not an ENOENT
		return fmt.Errorf("failed reading existing config: %w", err)
	}

	// Overwrite "our" entries, identified by name.
	for _, v := range template.Component.TaskOptions {
		for _, o := range v.Option {
			if o.Name == "name" {
				tasks[o.Value] = v
			}
		}
	}

	// Build new configuration
	options := make([]taskOption, 0, len(tasks))
	for _, t := range tasks {
		options = append(options, t)
	}

	out := buildConfig(options)

	err = out.atomicWriteFile(path.Join(projectDir, fileWatchersPath))
	if err != nil {
		return fmt.Errorf("failed writing to output file: %w", err)
	}

	return nil
}
