// Copyright 2017 Google Inc. All rights reserved.
//
// 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
//
//     http://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.

// This file provides a bpfix command-line library

// TODO(jeffrygaston) should this file be consolidated with bpfmt.go?

package cmd_lib

import (
	"bytes"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"

	"github.com/google/blueprint/parser"

	"android/soong/bpfix/bpfix"
)

var (
	// main operation modes
	list   = flag.Bool("l", false, "list files whose formatting differs from bpfmt's")
	write  = flag.Bool("w", false, "write result to (source) file instead of stdout")
	doDiff = flag.Bool("d", false, "display diffs instead of rewriting files")
)

var (
	exitCode = 0
)

func report(err error) {
	fmt.Fprintln(os.Stderr, err)
	exitCode = 2
}

func openAndProcess(filename string, out io.Writer, fixRequest bpfix.FixRequest) error {
	f, err := os.Open(filename)
	if err != nil {
		return err
	}
	defer f.Close()
	return processFile(filename, f, out, fixRequest)
}

// If in == nil, the source is the contents of the file with the given filename.
func processFile(filename string, in io.Reader, out io.Writer, fixRequest bpfix.FixRequest) error {
	// load the input file
	src, err := ioutil.ReadAll(in)
	if err != nil {
		return err
	}
	r := bytes.NewBuffer(append([]byte(nil), src...))
	file, errs := parser.Parse(filename, r, parser.NewScope(nil))
	if len(errs) > 0 {
		for _, err := range errs {
			fmt.Fprintln(os.Stderr, err)
		}
		return fmt.Errorf("%d parsing errors", len(errs))
	}

	// compute and apply any requested fixes
	fixer := bpfix.NewFixer(file)
	file, err = fixer.Fix(fixRequest)
	if err != nil {
		return err
	}

	// output the results
	res, err := parser.Print(file)
	if err != nil {
		return err
	}
	if !bytes.Equal(src, res) {
		// contents have changed
		if *list {
			fmt.Fprintln(out, filename)
		}
		if *write {
			err = ioutil.WriteFile(filename, res, 0644)
			if err != nil {
				return err
			}
		}
		if *doDiff {
			data, err := diff(src, res)
			if err != nil {
				return fmt.Errorf("computing diff: %s", err)
			}
			fmt.Printf("diff %s bpfix/%s\n", filename, filename)
			out.Write(data)
		}
	}
	if !*list && !*write && !*doDiff {
		_, err = out.Write(res)
	}
	return err
}

func makeFileVisitor(fixRequest bpfix.FixRequest) func(string, os.FileInfo, error) error {
	return func(path string, f os.FileInfo, err error) error {
		if err == nil && (f.Name() == "Blueprints" || f.Name() == "Android.bp") {
			err = openAndProcess(path, os.Stdout, fixRequest)
		}
		if err != nil {
			report(err)
		}
		return nil
	}
}

func walkDir(path string, fixRequest bpfix.FixRequest) {
	filepath.Walk(path, makeFileVisitor(fixRequest))
}

func Run() {
	flag.Parse()

	fixRequest := bpfix.NewFixRequest().AddAll()

	if flag.NArg() == 0 {
		if *write {
			fmt.Fprintln(os.Stderr, "error: cannot use -w with standard input")
			exitCode = 2
			return
		}
		if err := processFile("<standard input>", os.Stdin, os.Stdout, fixRequest); err != nil {
			report(err)
		}
		return
	}

	for i := 0; i < flag.NArg(); i++ {
		path := flag.Arg(i)
		switch dir, err := os.Stat(path); {
		case err != nil:
			report(err)
		case dir.IsDir():
			walkDir(path, fixRequest)
		default:
			if err := openAndProcess(path, os.Stdout, fixRequest); err != nil {
				report(err)
			}
		}
	}
}

func diff(b1, b2 []byte) (data []byte, err error) {
	f1, err := ioutil.TempFile("", "bpfix")
	if err != nil {
		return
	}
	defer os.Remove(f1.Name())
	defer f1.Close()

	f2, err := ioutil.TempFile("", "bpfix")
	if err != nil {
		return
	}
	defer os.Remove(f2.Name())
	defer f2.Close()

	f1.Write(b1)
	f2.Write(b2)

	data, err = exec.Command("diff", "-u", f1.Name(), f2.Name()).CombinedOutput()
	if len(data) > 0 {
		// diff exits with a non-zero status when the files don't match.
		// Ignore that failure as long as we get output.
		err = nil
	}
	return

}
