package main

import (
	"bufio"
	"flag"
	"fmt"
	"os"
	"regexp"
	"strconv"
	"strings"
)

var (
	input         = flag.String("i", "^.*?$", "input pattern")
	output        = flag.String("o", "{0}", "output pattern")
	keepUnmatched = flag.Bool("k", false, "keep unmatched lines")

	replacePattern = regexp.MustCompile("\\{(\\d+)(?::(.*?))?\\}")
)

func main() {
	flag.Parse()

	pattern, err := regexp.Compile(*input)
	if err != nil {
		panic(err)
	}

	r := bufio.NewReader(os.Stdin)
	for line, err := r.ReadString('\n'); err == nil; line, err = r.ReadString('\n') {
		line = line[:len(line)-1]
		matches := pattern.FindStringSubmatch(line)

		fmt.Println(matches)

		if len(matches) == 0 {
			if *keepUnmatched {
				fmt.Println(line)
			}
			continue
		}

		fmt.Println(replaceVars(*output, matches...))
	}
}

func replaceVars(format string, vars ...string) string {
	replacements := replacePattern.FindAllStringSubmatch(format, -1)

	for _, replacement := range replacements {
		rplStr := replacement[0]
		varIndex, _ := strconv.Atoi(replacement[1])
		rplFmt := replacement[2]

		// default format if not specified by user
		if rplFmt == "" {
			rplFmt = "%s"
		}

		if strings.HasSuffix(rplFmt, "d") { // replace integers
			value, _ := strconv.ParseInt(vars[varIndex], 10, 64)
			format = strings.Replace(format, rplStr, fmt.Sprintf(rplFmt, value), 1)
		} else if strings.HasSuffix(rplFmt, "f") { // replace floats
			value, _ := strconv.ParseFloat(vars[varIndex], 64)
			format = strings.Replace(format, rplStr, fmt.Sprintf(rplFmt, value), 1)
		} else { // replace strings
			format = strings.Replace(format, rplStr, fmt.Sprintf(rplFmt, vars[varIndex]), 1)
		}

	}

	return format
}
