/*
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 maven

import (
	"bytes"
	"encoding/xml"
	"fmt"
	"time"
)

// Repository --
type Repository struct {
	ID        string           `xml:"id"`
	Name      string           `xml:"name,omitempty"`
	URL       string           `xml:"url"`
	Snapshots RepositoryPolicy `xml:"snapshots,omitempty"`
	Releases  RepositoryPolicy `xml:"releases,omitempty"`
}

// RepositoryPolicy --
type RepositoryPolicy struct {
	Enabled        bool   `xml:"enabled"`
	UpdatePolicy   string `xml:"updatePolicy,omitempty"`
	ChecksumPolicy string `xml:"checksumPolicy,omitempty"`
}

// Build --
type Build struct {
	DefaultGoal string   `xml:"defaultGoal,omitempty"`
	Plugins     []Plugin `xml:"plugins>plugin,omitempty"`
}

// Plugin --
type Plugin struct {
	GroupID      string       `xml:"groupId"`
	ArtifactID   string       `xml:"artifactId"`
	Version      string       `xml:"version,omitempty"`
	Executions   []Execution  `xml:"executions>execution,omitempty"`
	Dependencies []Dependency `xml:"dependencies>dependency,omitempty"`
}

// Execution --
type Execution struct {
	ID    string   `xml:"id,omitempty"`
	Phase string   `xml:"phase,omitempty"`
	Goals []string `xml:"goals>goal,omitempty"`
}

// Properties --
type Properties map[string]string

type propertiesEntry struct {
	XMLName xml.Name
	Value   string `xml:",chardata"`
}

// MarshalXML --
func (m Properties) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
	if len(m) == 0 {
		return nil
	}

	err := e.EncodeToken(start)
	if err != nil {
		return err
	}

	for k, v := range m {
		if err := e.Encode(propertiesEntry{XMLName: xml.Name{Local: k}, Value: v}); err != nil {
			return err
		}
	}

	return e.EncodeToken(start.End())
}

// NewContext --
func NewContext(buildDir string, project Project) Context {
	return Context{
		Path:                buildDir,
		Project:             project,
		AdditionalArguments: make([]string, 0),
		AdditionalEntries:   make(map[string]interface{}),
	}
}

// Context --
type Context struct {
	Path                string
	Project             Project
	SettingsContent     []byte
	AdditionalArguments []string
	AdditionalEntries   map[string]interface{}
	Timeout             time.Duration
	LocalRepository     string
}

// AddEntry --
func (c *Context) AddEntry(id string, entry interface{}) {
	if c.AdditionalEntries == nil {
		c.AdditionalEntries = make(map[string]interface{})
	}

	c.AdditionalEntries[id] = entry
}

// AddArgument --
func (c *Context) AddArgument(argument string) {
	c.AdditionalArguments = append(c.AdditionalArguments, argument)
}

// AddArgumentf --
func (c *Context) AddArgumentf(format string, args ...interface{}) {
	c.AdditionalArguments = append(c.AdditionalArguments, fmt.Sprintf(format, args...))
}

// AddArguments --
func (c *Context) AddArguments(arguments ...string) {
	c.AdditionalArguments = append(c.AdditionalArguments, arguments...)
}

// AddSystemProperty --
func (c *Context) AddSystemProperty(name string, value string) {
	c.AddArgumentf("-D%s=%s", name, value)
}

// Settings represent a maven settings
type Settings struct {
	XMLName           xml.Name
	XMLNs             string    `xml:"xmlns,attr"`
	XMLNsXsi          string    `xml:"xmlns:xsi,attr"`
	XsiSchemaLocation string    `xml:"xsi:schemaLocation,attr"`
	LocalRepository   string    `xml:"localRepository"`
	Profiles          []Profile `xml:"profiles>profile,omitempty"`
}

// MarshalBytes --
func (s Settings) MarshalBytes() ([]byte, error) {
	w := &bytes.Buffer{}
	w.WriteString(xml.Header)

	e := xml.NewEncoder(w)
	e.Indent("", "  ")

	err := e.Encode(s)
	if err != nil {
		return []byte{}, err
	}

	return w.Bytes(), nil
}

// Project represent a maven project
type Project struct {
	XMLName              xml.Name
	XMLNs                string                `xml:"xmlns,attr"`
	XMLNsXsi             string                `xml:"xmlns:xsi,attr"`
	XsiSchemaLocation    string                `xml:"xsi:schemaLocation,attr"`
	ModelVersion         string                `xml:"modelVersion"`
	GroupID              string                `xml:"groupId"`
	ArtifactID           string                `xml:"artifactId"`
	Version              string                `xml:"version"`
	Properties           Properties            `xml:"properties,omitempty"`
	DependencyManagement *DependencyManagement `xml:"dependencyManagement"`
	Dependencies         []Dependency          `xml:"dependencies>dependency,omitempty"`
	Repositories         []Repository          `xml:"repositories>repository,omitempty"`
	PluginRepositories   []Repository          `xml:"pluginRepositories>pluginRepository,omitempty"`
	Build                *Build                `xml:"build,omitempty"`
}

// Exclusion represent a maven's dependency exlucsion
type Exclusion struct {
	GroupID    string `xml:"groupId" yaml:"groupId"`
	ArtifactID string `xml:"artifactId" yaml:"artifactId"`
}

// DependencyManagement represent maven's dependency management block
type DependencyManagement struct {
	Dependencies []Dependency `xml:"dependencies>dependency,omitempty"`
}

// Dependency represent a maven's dependency
type Dependency struct {
	GroupID    string       `xml:"groupId" yaml:"groupId"`
	ArtifactID string       `xml:"artifactId" yaml:"artifactId"`
	Version    string       `xml:"version,omitempty" yaml:"version,omitempty"`
	Type       string       `xml:"type,omitempty" yaml:"type,omitempty"`
	Classifier string       `xml:"classifier,omitempty" yaml:"classifier,omitempty"`
	Scope      string       `xml:"scope,omitempty" yaml:"scope,omitempty"`
	Exclusions *[]Exclusion `xml:"exclusions>exclusion,omitempty" yaml:"exclusions,omitempty"`
}

// Profile --
type Profile struct {
	ID                 string       `xml:"id"`
	Activation         Activation   `xml:"activation,omitempty"`
	Properties         Properties   `xml:"properties,omitempty"`
	Repositories       []Repository `xml:"repositories>repository,omitempty"`
	PluginRepositories []Repository `xml:"pluginRepositories>pluginRepository,omitempty"`
}

// Activation --
type Activation struct {
	ActiveByDefault bool                `xml:"activeByDefault"`
	Property        *PropertyActivation `xml:"property,omitempty"`
}

// PropertyActivation --
type PropertyActivation struct {
	Name  string `xml:"name"`
	Value string `xml:"value"`
}
