// Copyright 2020 The Wuffs Authors.
//
// 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
//
//    https://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.

// ----------------

// dumbindent formats C (and C-like) programs.
//
// Without explicit paths, it rewrites the standard input to standard output.
// Otherwise, the -l (list files that would change) or -w (write files in
// place) or both flags must be given. Given a file path, it operates on that
// file; given a directory path, it operates on all *.{c,h} files in that
// directory, recursively. File paths starting with a period are ignored.
//
// Pass -spaces=N or -tabs to use N spaces or 1 tab per indent level. The
// default is 2 spaces per indent level.
//
// It is similar in concept to pretty-printers like `indent` or `clang-format`.
// It is much dumber (it will not add or remove line breaks or otherwise
// re-flow lines of code just to fit within an 80 column limit) but it can
// therefore be much faster at the basic task of automatically indenting nested
// blocks. The output isn't 'perfect', but it's usually sufficiently readable
// if the input already has sensible line breaks.
//
// To quantify "much faster", on this one C file, this program was 80 times
// faster than `clang-format`, even without a column limit:
//
//     $ wc release/c/wuffs-v0.2.c
//      11858  35980 431885 release/c/wuffs-v0.2.c
//     $ time dumbindent                               < release/c/wuffs-v0.2.c > /dev/null
//     real    0m0.008s
//     user    0m0.005s
//     sys     0m0.005s
//     $ time clang-format-9                           < release/c/wuffs-v0.2.c > /dev/null
//     real    0m0.668s
//     user    0m0.618s
//     sys     0m0.032s
//     $ time clang-format-9 -style='{ColumnLimit: 0}' < release/c/wuffs-v0.2.c > /dev/null
//     real    0m0.641s
//     user    0m0.585s
//     sys     0m0.037s
//
// More commentary is at:
// https://godoc.org/github.com/google/wuffs/lib/dumbindent
// https://nigeltao.github.io/blog/2020/dumbindent.html
package main

import (
	"bytes"
	"errors"
	"flag"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"runtime"
	"strings"

	"github.com/google/wuffs/lib/dumbindent"
)

var (
	lFlag = flag.Bool("l", false, "list files whose formatting differs from dumbindent's")
	wFlag = flag.Bool("w", false, "write result to (source) file instead of stdout")

	spacesFlag = flag.Int("spaces", 2, "the number of spaces per indent")
	tabsFlag   = flag.Bool("tabs", false, "indent with a tab instead of spaces")
)

func usage() {
	fmt.Fprintf(os.Stderr, "usage: dumbindent [flags] [path ...]\n")
	flag.PrintDefaults()
}

func main() {
	if err := main1(); err != nil {
		os.Stderr.WriteString(err.Error() + "\n")
		os.Exit(1)
	}
}

func main1() error {
	flag.Usage = usage
	flag.Parse()

	if flag.NArg() == 0 {
		if *lFlag {
			return errors.New("cannot use -l with standard input")
		}
		if *wFlag {
			return errors.New("cannot use -w with standard input")
		}
		return do(os.Stdin, "<standard input>")
	}

	if !*lFlag && !*wFlag {
		return errors.New("must use -l or -w if paths are given")
	}

	for i := 0; i < flag.NArg(); i++ {
		arg := flag.Arg(i)
		switch dir, err := os.Stat(arg); {
		case err != nil:
			return err
		case dir.IsDir():
			return filepath.Walk(arg, walk)
		default:
			if err := do(nil, arg); err != nil {
				return err
			}
		}
	}

	return nil
}

func isCHFile(info os.FileInfo) bool {
	name := info.Name()
	return !info.IsDir() && !strings.HasPrefix(name, ".") &&
		(strings.HasSuffix(name, ".c") || strings.HasSuffix(name, ".h"))
}

func walk(filename string, info os.FileInfo, err error) error {
	if (err == nil) && isCHFile(info) {
		err = do(nil, filename)
	}
	// Don't complain if a file was deleted in the meantime (i.e. the directory
	// changed concurrently while running this program).
	if (err != nil) && !os.IsNotExist(err) {
		return err
	}
	return nil
}

func do(r io.Reader, filename string) error {
	src, err := []byte(nil), error(nil)
	if r != nil {
		src, err = io.ReadAll(r)
	} else {
		src, err = os.ReadFile(filename)
	}
	if err != nil {
		return err
	}

	dst := dumbindent.FormatBytes(nil, src, &dumbindent.Options{
		Spaces: *spacesFlag,
		Tabs:   *tabsFlag,
	})

	if r != nil {
		if _, err := os.Stdout.Write(dst); err != nil {
			return err
		}
	} else if !bytes.Equal(dst, src) {
		if *lFlag {
			fmt.Println(filename)
		}
		if *wFlag {
			if err := writeFile(filename, dst); err != nil {
				return err
			}
		}
	}

	return nil
}

const chmodSupported = runtime.GOOS != "windows"

func writeFile(filename string, b []byte) error {
	f, err := os.CreateTemp(filepath.Dir(filename), filepath.Base(filename))
	if err != nil {
		return err
	}
	if chmodSupported {
		if info, err := os.Stat(filename); err == nil {
			f.Chmod(info.Mode().Perm())
		}
	}
	_, werr := f.Write(b)
	cerr := f.Close()
	if werr != nil {
		os.Remove(f.Name())
		return werr
	}
	if cerr != nil {
		os.Remove(f.Name())
		return cerr
	}
	return os.Rename(f.Name(), filename)
}
