// 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"
	"io/ioutil"
	"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 = ioutil.ReadAll(r)
	} else {
		src, err = ioutil.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 := ioutil.TempFile(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)
}
