// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package html

import (
	"template/parse"
)

// clone clones a template Node.
func clone(n parse.Node) parse.Node {
	switch t := n.(type) {
	case *parse.ActionNode:
		return cloneAction(t)
	case *parse.IfNode:
		b := new(parse.IfNode)
		copyBranch(&b.BranchNode, &t.BranchNode)
		return b
	case *parse.ListNode:
		return cloneList(t)
	case *parse.RangeNode:
		b := new(parse.RangeNode)
		copyBranch(&b.BranchNode, &t.BranchNode)
		return b
	case *parse.TemplateNode:
		return cloneTemplate(t)
	case *parse.TextNode:
		return cloneText(t)
	case *parse.WithNode:
		b := new(parse.WithNode)
		copyBranch(&b.BranchNode, &t.BranchNode)
		return b
	}
	panic("cloning " + n.String() + " is unimplemented")
}

// cloneAction returns a deep clone of n.
func cloneAction(n *parse.ActionNode) *parse.ActionNode {
	// We use keyless fields because they won't compile if a field is added.
	return &parse.ActionNode{n.NodeType, n.Line, clonePipe(n.Pipe)}
}

// cloneList returns a deep clone of n.
func cloneList(n *parse.ListNode) *parse.ListNode {
	if n == nil {
		return nil
	}
	// We use keyless fields because they won't compile if a field is added.
	c := parse.ListNode{n.NodeType, make([]parse.Node, len(n.Nodes))}
	for i, child := range n.Nodes {
		c.Nodes[i] = clone(child)
	}
	return &c
}

// clonePipe returns a shallow clone of n.
// The escaper does not modify pipe descendants in place so there's no need to
// clone deeply.
func clonePipe(n *parse.PipeNode) *parse.PipeNode {
	if n == nil {
		return nil
	}
	// We use keyless fields because they won't compile if a field is added.
	return &parse.PipeNode{n.NodeType, n.Line, n.Decl, n.Cmds}
}

// cloneTemplate returns a deep clone of n.
func cloneTemplate(n *parse.TemplateNode) *parse.TemplateNode {
	// We use keyless fields because they won't compile if a field is added.
	return &parse.TemplateNode{n.NodeType, n.Line, n.Name, clonePipe(n.Pipe)}
}

// cloneText clones the given node sharing its []byte.
func cloneText(n *parse.TextNode) *parse.TextNode {
	// We use keyless fields because they won't compile if a field is added.
	return &parse.TextNode{n.NodeType, n.Text}
}

// copyBranch clones src into dst.
func copyBranch(dst, src *parse.BranchNode) {
	// We use keyless fields because they won't compile if a field is added.
	*dst = parse.BranchNode{
		src.NodeType,
		src.Line,
		clonePipe(src.Pipe),
		cloneList(src.List),
		cloneList(src.ElseList),
	}
}
