// Copyright 2020 The Fuchsia 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 codifier

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strings"
)

// orderedStrings provides list functions that maintain an unsorted, ordered
// slice of strings, allowing additions of non-present, non-blank strings. That
// is, the list will be an ordered set provided that the list these functions
// are applied to is already an ordered set. File reading and appending
// functions are provided.
type orderedStrings []string

// contains returns whether the list contains the item.
func (o orderedStrings) contains(item string) bool {
	for _, l := range o {
		if l == item {
			return true
		}
	}
	return false
}

// Add appends the item(s) to the list if they are neither blank nor already
// present. Returns true iff all of the items are added.
//
// TODO(gboone@): This function is exported currently so that files can be added
// to changedFiles list by external functions. But changes to internal data
// should be made through Proc operators. Add operators to wrap these functions,
// eg (p *Proc) AddChangedFile(f string), to ordered_list_ops.go for managing
// the changedFiles list. Then unexport this function.
func (o *orderedStrings) Add(items ...string) bool {
	if len(items) == 0 {
		return false
	}
	allAdded := true
	for _, item := range items {
		if item == "" || o.contains(item) {
			allAdded = false
			continue
		}
		*o = append(*o, item)
	}
	return allAdded
}

func orderedStringsLoad(r io.Reader) (orderedStrings, error) {
	scanner := bufio.NewScanner(r)
	var o orderedStrings
	for scanner.Scan() {
		line := scanner.Text()
		if l := strings.Index(line, "#"); l != -1 {
			line = line[:l]
		}
		if line = strings.Trim(line, "\t "); line != "" {
			if !o.Add(line) {
				return nil, fmt.Errorf("found duplicate entry %q", line)
			}
		}
	}
	return o, scanner.Err()
}

// orderedStringsFromFile reads the lines into a string slice, stripping comment lines
// starting with '#' and text after '#' on lines.
func orderedStringsFromFile(filename string) (orderedStrings, error) {
	filePath, err := resolveGnPath("", filename)
	if err != nil {
		return nil, fmt.Errorf("can't resolve path for filename %q: %w", filename, err)
	}
	f, err := os.Open(filePath)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	return orderedStringsLoad(f)
}

// findMissing returns the first candidate that isn't present in the named file.
// Return the index and the picked value, a boolean indicating whether one was
// found, and any error.
func findMissing(candidates []string, fileName string) (int, string, bool, error) {
	skiplist, err := orderedStringsFromFile(fileName)
	if err != nil {
		return 0, "", false, err
	}
	for i, candidate := range candidates {
		if !skiplist.contains(candidate) {
			return i, candidate, true, nil
		}
	}
	return 0, "", false, nil
}

// GoString serializes the string. Use like `fmt.Printf("%#v", o)`.
func (o orderedStrings) GoString() string {
	out := ""
	for i, item := range o {
		out += fmt.Sprintf("  %d: %q", i, item)
		if len(o)-1 != i {
			out += "\n"
		}
	}
	return out
}
