// 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 (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strings"

	"fidl/compiler/backend/types"
)

// flagsDef defines the LLCPP flags schema.
type flagsDef struct {
	jsonPath    *string
	header      *string
	source      *string
	includeBase *string
}

var flags = func() flagsDef {
	return 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 != ""
}

type config struct {
	fidl              types.Root
	headerPath        string
	sourcePath        string
	primaryHeaderPath string
}

// decodeTypes decodes FIDL type information from the JSON file specified as an argument.
func decodeTypes(jsonPath string) (types.Root, error) {
	bytes, err := ioutil.ReadFile(jsonPath)
	if err != nil {
		return types.Root{}, fmt.Errorf("error reading from %s: %v", jsonPath, err)
	}

	var fidl types.Root
	err = json.Unmarshal(bytes, &fidl)
	if err != nil {
		return types.Root{}, fmt.Errorf("error parsing JSON as FIDL data: %v", err)
	}

	for _, l := range fidl.Libraries {
		for k, v := range l.Decls {
			fidl.Decls[types.EnsureLibrary(l.Name, k)] = v
		}
	}

	return fidl, nil
}

func (f flagsDef) getConfig() (config, error) {
	fidl, err := decodeTypes(*f.jsonPath)

	headerPath, err := filepath.Abs(*f.header)
	if err != nil {
		return config{}, err
	}

	sourcePath, err := filepath.Abs(*f.source)
	if err != nil {
		return config{}, err
	}

	var primaryHeaderPath string
	if *f.includeBase != "" {
		absoluteIncludeBase, err := filepath.Abs(*f.includeBase)
		if err != nil {
			return config{}, err
		}
		if !strings.HasPrefix(headerPath, absoluteIncludeBase) {
			return config{}, fmt.Errorf("include-base (%v) is not a parent of header (%v)", absoluteIncludeBase, headerPath)
		}
		relStem, err := filepath.Rel(*f.includeBase, *f.header)
		if err != nil {
			return config{}, err
		}
		primaryHeaderPath = relStem
	} else {
		// 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")
		primaryHeaderPath = filepath.Join(parts...)
	}

	return config{
		fidl:              fidl,
		headerPath:        headerPath,
		sourcePath:        sourcePath,
		primaryHeaderPath: primaryHeaderPath,
	}, nil
}

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

	config, err := flags.getConfig()
	if err != nil {
		log.Fatalf("Error getting config: %v", err)
	}

	generator := newGenerator()
	err = generator.generateFidl(config)
	if err != nil {
		log.Fatalf("Error running generator: %v", err)
	}
}
