package main

import (
	"flag"
	"os/exec"
	"path/filepath"
	"fmt"
	"os"
	"strings"
)

var removeArchives *bool

func processPath(curPath string) error {
	info, err := os.Stat(curPath)
	if err != nil {
		return fmt.Errorf("Unable to stat %s: %s", curPath, err.Error())
	}
	if info.IsDir() {
		entries, err := os.ReadDir(curPath)
		if err != nil {
			return fmt.Errorf("Unable to call readdir on %s: %s", curPath, err.Error())
		}
		for i := range(entries) {
			err := processPath(filepath.Join(curPath, entries[i].Name()))
			if err != nil {
				return err
			}
		}
	} else {
		tarBaseName := tarBaseName(curPath)
		if tarBaseName != "" {
			err = applyTarOn(curPath)
			if err != nil {
				return err
			}
			err = processPath(filepath.Join(filepath.Dir(curPath), tarBaseName))
			if err != nil {
				return err
			}
			if *removeArchives {
				err = os.Remove(curPath)
				if err != nil {
					return fmt.Errorf("Unable to remove archive file %s: %s", curPath, err.Error())
				}
				fmt.Printf("== rm %s\n", curPath)
			}
		}
	}
	return nil
}

func tarBaseName(curPath string) string {
	if strings.HasSuffix(curPath, ".tgz") {
		return filepath.Base(curPath[:len(curPath)-4])
	}
	return ""
}

func applyTarOn(curPath string) error {
	fmt.Printf("== decompressing tar file %s\n", curPath)
	cmd := exec.Command("tar", "xvf", filepath.Base(curPath))
	cmd.Dir = filepath.Dir(curPath)
	//cmd.Stdout = os.Stdout
	err := cmd.Run()
	if err != nil {
		return fmt.Errorf("error running tar xvf on %s: %s", curPath, err.Error())
	}
	return nil
}

func main() {
	removeArchives = flag.Bool("r", false, "Remove archive files after decompressing them")
	flag.Usage = func() {
		fmt.Printf("recursive_decompress: recursively decompresses a path.\n")
		fmt.Printf("usage: recursive_decompress [flags] [paths...]\n")
		fmt.Printf("\n")
		flag.PrintDefaults()
	}
	flag.Parse()
	curPath := "."
	if flag.Arg(0) != "" {
		curPath = flag.Arg(0)
	}
	err := processPath(curPath)
	if err != nil {
		fmt.Printf("error: %s\n", err.Error())
		os.Exit(1)
	}
	os.Exit(0)
}