// Copyright 2018 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 gndoc

import (
	"context"
	"encoding/json"
	"fmt"
	"os"
	"strings"
)

// Arg holds the information directly parsed from the json output of `gn args <build> --list --json`.
type Arg struct {
	Name       string   `json:"name"`
	CurrentVal argValue `json:"current"`
	DefaultVal argValue `json:"default"`
	Comment    string   `json:"comment"`
	Key        string   `json: "-"`
}

// ArgValue holds a value, its filepath and line number, and the build associated with the value.
type argValue struct {
	Val  string `json:"value"`
	File string `json:"file"`
	Line int    `json:"line"`
}

// ParseGNArgs runs the necessary gn commands and decodes the json output into a channel of GNArgs.
func ParseGNArgs(ctx context.Context, inputFiles []string, keyArgs []string) (<-chan Arg, <-chan error) {
	args := make(chan Arg)
	errs := make(chan error, 1)
	go func() {
		defer func() {
			close(args)
			close(errs)
		}()
		for _, input := range inputFiles {
			select {
			case <-ctx.Done():
				return
			default:
				err := parseJson(input, keyArgs, args)
				if err != nil {
					errs <- err
					return
				}
			}
		}
	}()
	return args, errs
}

func parseJson(input string, keyArgs []string, out chan<- Arg) error {
	// Open the json file.
	file, err := os.Open(input)
	if err != nil {
		return err
	}
	defer file.Close()

	// Decode the json into GNArgs.
	var gnArgs []Arg
	decoder := json.NewDecoder(file)
	if err := decoder.Decode(&gnArgs); err != nil {
		return err
	}

	// Mark the args with the relevant key and send to channel.
	key := getKey(gnArgs, keyArgs)
	for _, arg := range gnArgs {
		arg.Key = key
		out <- arg
	}

	return nil
}

// TODO: make sure this is sorted before stringifying
// getKey searches the decoded json for the flagged keys and builds the marker string.
func getKey(args []Arg, keys []string) string {
	keyVals := make([]string, len(keys))
	for _, arg := range args {
		for idx, key := range keys {
			if arg.Name == key {
				keyVals[idx] = fmt.Sprintf("%s = %v", key, arg.CurrentVal.Val)
			}
		}
	}
	return strings.Join(keyVals, ", ")
}
