// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"path/filepath"
	"strings"

	"fidl/compiler/backend/cpp"
	"fidl/compiler/backend/types"
	"fidl/compiler/llcpp_backend/codegen"
)

type flagsDef struct {
	jsonPath    *string
	header      *string
	source      *string
	includeBase *string
}

var flags = flagsDef{
	jsonPath: flag.String("json", "",
		"relative path to the FIDL intermediate representation."),
	header: flag.String("header", "",
		"the output path for the generated header."),
	source: flag.String("source", "",
		"the output path for the generated C++ implementation."),
	includeBase: flag.String("include-base", "",
		"[optional] the directory relative to which includes will be computed. "+
			"If omitted, assumes #include <fidl/library/name/llcpp/fidl.h>"),
}

// valid returns true if the parsed flags are valid.
func (f flagsDef) valid() bool {
	return *f.jsonPath != "" && *f.header != "" && *f.source != ""
}

func calcPrimaryHeader(fidl types.Root, headerPath string) (string, error) {
	if *flags.includeBase != "" {
		absoluteIncludeBase, err := filepath.Abs(*flags.includeBase)
		if err != nil {
			return "", err
		}
		if !strings.HasPrefix(headerPath, absoluteIncludeBase) {
			return "", fmt.Errorf("include-base (%v) is not a parent of header (%v)", absoluteIncludeBase, headerPath)
		}
		relStem, err := filepath.Rel(*flags.includeBase, *flags.header)
		if err != nil {
			return "", err
		}
		return relStem, nil
	}

	// Assume the convention for including fidl library dependencies, i.e.
	// #include <fuchsia/library/name/llcpp/fidl.h>
	var parts []string
	for _, part := range fidl.Name.Parts() {
		parts = append(parts, string(part))
	}
	parts = append(parts, "llcpp", "fidl.h")
	return filepath.Join(parts...), nil
}

func main() {
	flag.Parse()
	if !flag.Parsed() || !flags.valid() {
		flag.PrintDefaults()
		os.Exit(1)
	}

	fidl, err := types.ReadJSONIr(*flags.jsonPath)
	if err != nil {
		log.Fatal(err)
	}
	tree := cpp.CompileLL(fidl)

	headerPath, err := filepath.Abs(*flags.header)
	if err != nil {
		log.Fatal(err)
	}

	sourcePath, err := filepath.Abs(*flags.source)
	if err != nil {
		log.Fatal(err)
	}

	primaryHeader, err := calcPrimaryHeader(fidl, headerPath)
	if err != nil {
		log.Fatal(err)
	}
	tree.PrimaryHeader = primaryHeader

	generator := codegen.NewGenerator()
	if err := generator.GenerateHeader(tree, headerPath); err != nil {
		log.Fatalf("Error running header generator: %v", err)
	}
	if err := generator.GenerateSource(tree, sourcePath); err != nil {
		log.Fatalf("Error running source generator: %v", err)
	}
}
