// Copyright 2014 Google Inc. All rights reserved.
//
// 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 parser

import (
	"sort"
	"text/scanner"
)

func SortLists(file *File) {
	for _, def := range file.Defs {
		if assignment, ok := def.(*Assignment); ok {
			sortListsInValue(assignment.Value, file)
		} else if module, ok := def.(*Module); ok {
			for _, prop := range module.Properties {
				sortListsInValue(prop.Value, file)
			}
		}
	}
	sort.Sort(commentsByOffset(file.Comments))
}

func SortList(file *File, list *List) {
	for i := 0; i < len(list.Values); i++ {
		// Find a set of values on contiguous lines
		line := list.Values[i].Pos().Line
		var j int
		for j = i + 1; j < len(list.Values); j++ {
			if list.Values[j].Pos().Line > line+1 {
				break
			}
			line = list.Values[j].Pos().Line
		}

		nextPos := list.End()
		if j < len(list.Values) {
			nextPos = list.Values[j].Pos()
		}
		sortSubList(list.Values[i:j], nextPos, file)
		i = j - 1
	}
}

func ListIsSorted(list *List) bool {
	for i := 0; i < len(list.Values); i++ {
		// Find a set of values on contiguous lines
		line := list.Values[i].Pos().Line
		var j int
		for j = i + 1; j < len(list.Values); j++ {
			if list.Values[j].Pos().Line > line+1 {
				break
			}
			line = list.Values[j].Pos().Line
		}

		if !subListIsSorted(list.Values[i:j]) {
			return false
		}
		i = j - 1
	}

	return true
}

func sortListsInValue(value Expression, file *File) {
	switch v := value.(type) {
	case *Variable:
		// Nothing
	case *Operator:
		sortListsInValue(v.Args[0], file)
		sortListsInValue(v.Args[1], file)
	case *Map:
		for _, p := range v.Properties {
			sortListsInValue(p.Value, file)
		}
	case *List:
		SortList(file, v)
	}
}

func sortSubList(values []Expression, nextPos scanner.Position, file *File) {
	l := make(elemList, len(values))
	for i, v := range values {
		s, ok := v.(*String)
		if !ok {
			panic("list contains non-string element")
		}
		n := nextPos
		if i < len(values)-1 {
			n = values[i+1].Pos()
		}
		l[i] = elem{s.Value, i, v.Pos(), n}
	}

	sort.Sort(l)

	copyValues := append([]Expression{}, values...)
	copyComments := make([]*CommentGroup, len(file.Comments))
	for i := range file.Comments {
		cg := *file.Comments[i]
		cg.Comments = make([]*Comment, len(cg.Comments))
		for j := range file.Comments[i].Comments {
			c := *file.Comments[i].Comments[j]
			cg.Comments[j] = &c
		}
		copyComments[i] = &cg
	}

	curPos := values[0].Pos()
	for i, e := range l {
		values[i] = copyValues[e.i]
		values[i].(*String).LiteralPos = curPos
		for j, c := range copyComments {
			if c.Pos().Offset > e.pos.Offset && c.Pos().Offset < e.nextPos.Offset {
				file.Comments[j].Comments[0].Slash.Line = curPos.Line
				file.Comments[j].Comments[0].Slash.Offset += values[i].Pos().Offset - e.pos.Offset
			}
		}

		curPos.Offset += e.nextPos.Offset - e.pos.Offset
		curPos.Line++
	}
}

func subListIsSorted(values []Expression) bool {
	prev := ""
	for _, v := range values {
		s, ok := v.(*String)
		if !ok {
			panic("list contains non-string element")
		}
		if prev > s.Value {
			return false
		}
		prev = s.Value
	}

	return true
}

type elem struct {
	s       string
	i       int
	pos     scanner.Position
	nextPos scanner.Position
}

type elemList []elem

func (l elemList) Len() int {
	return len(l)
}

func (l elemList) Swap(i, j int) {
	l[i], l[j] = l[j], l[i]
}

func (l elemList) Less(i, j int) bool {
	return l[i].s < l[j].s
}

type commentsByOffset []*CommentGroup

func (l commentsByOffset) Len() int {
	return len(l)
}

func (l commentsByOffset) Less(i, j int) bool {
	return l[i].Pos().Offset < l[j].Pos().Offset
}

func (l commentsByOffset) Swap(i, j int) {
	l[i], l[j] = l[j], l[i]
}
