// Copyright 2018 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 dart

import (
	"bytes"
	"fmt"
	"strings"
	"text/template"

	gidlconfig "go.fuchsia.dev/fuchsia/tools/fidl/gidl/config"
	gidlir "go.fuchsia.dev/fuchsia/tools/fidl/gidl/ir"
	gidlmixer "go.fuchsia.dev/fuchsia/tools/fidl/gidl/mixer"
	fidl "go.fuchsia.dev/fuchsia/tools/fidl/lib/fidlgen"
)

var tmpl = template.Must(template.New("tmpls").Parse(`
// @dart = 2.8

// Ignore unused imports so that GIDL tests can be commented out without error.
// ignore_for_file: unused_import

import 'dart:typed_data';

import 'package:test/test.dart';
import 'package:fidl/fidl.dart' as fidl;
import 'package:topaz.lib.gidl/gidl.dart';
import 'package:topaz.lib.gidl/handles.dart';
import 'package:zircon/zircon.dart';

import 'package:fidl_conformance/fidl_async.dart';

void main() {
	group('conformance', () {
		group('encode success cases', () {
			{{ range .EncodeSuccessCases }}
			{{- if .HandleDefs }}
			EncodeSuccessCase.runWithHandles(
				{{ .EncoderName }},
				{{ .Name }},
				(List<Handle> handleDefs) => {{ .Value }},
				{{ .ValueType }},
				{{ .Bytes }},
				{{ .HandleDefs }},
				{{ .Handles }});
			{{- else }}
			EncodeSuccessCase.run(
				{{ .EncoderName }},
				{{ .Name }},
				{{ .Value }},
				{{ .ValueType }},
				{{ .Bytes }});
            {{- end }}
			{{ end }}
				});

		group('decode success cases', () {
			{{ range .DecodeSuccessCases }}
			{{- if .HandleDefs }}
			DecodeSuccessCase.runWithHandles(
				{{ .DecoderName }},
				{{ .Name }},
				(List<Handle> handleDefs) => {{ .Value }},
				{{ .ValueType }},
				{{ .Bytes }},
				{{ .HandleDefs }},
				{{ .Handles }},
				{{ .UnusedHandles }});
			{{- else }}
			DecodeSuccessCase.run(
				{{ .DecoderName }},
				{{ .Name }},
				{{ .Value }},
				{{ .ValueType }},
				{{ .Bytes }});
            {{- end }}
			{{ end }}
				});

		group('encode failure cases', () {
			{{ range .EncodeFailureCases }}
			{{- if .HandleDefs }}
			EncodeFailureCase.runWithHandles(
				{{ .EncoderName }},
				{{ .Name }},
				(List<Handle> handleDefs) => {{ .Value }},
				{{ .ValueType }},
				{{ .ErrorCode }},
				{{ .HandleDefs }});
			{{- else }}
			EncodeFailureCase.run(
				{{ .EncoderName }},
				{{ .Name }},
				() => {{ .Value }},
				{{ .ValueType }},
				{{ .ErrorCode }});
			{{- end }}
			{{ end }}
				});

		group('decode failure cases', () {
			{{ range .DecodeFailureCases }}
			DecodeFailureCase.run(
				{{ .DecoderName }},
				{{ .Name }},
				{{ .ValueType }},
				{{ .Bytes }},
			{{- if .HandleDefs }}
				{{ .ErrorCode }},
				{{ .HandleDefs }},
				{{ .Handles }});
			{{- else }}
				{{ .ErrorCode }});
			{{- end }}
			{{ end }}
				});
	});
}
`))

type tmplInput struct {
	EncodeSuccessCases []encodeSuccessCase
	DecodeSuccessCases []decodeSuccessCase
	EncodeFailureCases []encodeFailureCase
	DecodeFailureCases []decodeFailureCase
}

type encodeSuccessCase struct {
	EncoderName, Name, Value, ValueType, Bytes, HandleDefs, Handles string
}

type decodeSuccessCase struct {
	DecoderName, Name, Value, ValueType, Bytes, HandleDefs, Handles, UnusedHandles string
}

type encodeFailureCase struct {
	EncoderName, Name, Value, ValueType, ErrorCode, HandleDefs string
}

type decodeFailureCase struct {
	DecoderName, Name, ValueType, Bytes, ErrorCode, HandleDefs, Handles string
}

// Generate generates dart tests.
func GenerateConformanceTests(gidl gidlir.All, fidl fidl.Root, config gidlconfig.GeneratorConfig) ([]byte, error) {
	schema := gidlmixer.BuildSchema(fidl)
	encodeSuccessCases, err := encodeSuccessCases(gidl.EncodeSuccess, schema)
	if err != nil {
		return nil, err
	}
	decodeSuccessCases, err := decodeSuccessCases(gidl.DecodeSuccess, schema)
	if err != nil {
		return nil, err
	}
	encodeFailureCases, err := encodeFailureCases(gidl.EncodeFailure, schema)
	if err != nil {
		return nil, err
	}
	decodeFailureCases, err := decodeFailureCases(gidl.DecodeFailure, schema)
	if err != nil {
		return nil, err
	}
	var buf bytes.Buffer
	err = tmpl.Execute(&buf, tmplInput{
		EncodeSuccessCases: encodeSuccessCases,
		DecodeSuccessCases: decodeSuccessCases,
		EncodeFailureCases: encodeFailureCases,
		DecodeFailureCases: decodeFailureCases,
	})
	return buf.Bytes(), err
}

func encodeSuccessCases(gidlEncodeSuccesses []gidlir.EncodeSuccess, schema gidlmixer.Schema) ([]encodeSuccessCase, error) {
	var encodeSuccessCases []encodeSuccessCase
	for _, encodeSuccess := range gidlEncodeSuccesses {
		decl, err := schema.ExtractDeclaration(encodeSuccess.Value, encodeSuccess.HandleDefs)
		if err != nil {
			return nil, fmt.Errorf("encode success %s: %s", encodeSuccess.Name, err)
		}
		valueStr := visit(encodeSuccess.Value, decl)
		valueType := typeName(decl)
		for _, encoding := range encodeSuccess.Encodings {
			if !wireFormatSupported(encoding.WireFormat) {
				continue
			}
			encodeSuccessCases = append(encodeSuccessCases, encodeSuccessCase{
				EncoderName: encoderName(encoding.WireFormat),
				Name:        testCaseName(encodeSuccess.Name, encoding.WireFormat),
				Value:       valueStr,
				ValueType:   valueType,
				Bytes:       buildBytes(encoding.Bytes),
				HandleDefs:  buildHandleDefs(encodeSuccess.HandleDefs),
				Handles:     toDartIntList(encoding.Handles),
			})
		}
	}
	return encodeSuccessCases, nil
}

func decodeSuccessCases(gidlDecodeSuccesses []gidlir.DecodeSuccess, schema gidlmixer.Schema) ([]decodeSuccessCase, error) {
	var decodeSuccessCases []decodeSuccessCase
	for _, decodeSuccess := range gidlDecodeSuccesses {
		decl, err := schema.ExtractDeclaration(decodeSuccess.Value, decodeSuccess.HandleDefs)
		if err != nil {
			return nil, fmt.Errorf("decode success %s: %s", decodeSuccess.Name, err)
		}
		valueStr := visit(decodeSuccess.Value, decl)
		valueType := typeName(decl)
		for _, encoding := range decodeSuccess.Encodings {
			if !wireFormatSupported(encoding.WireFormat) {
				continue
			}
			decodeSuccessCases = append(decodeSuccessCases, decodeSuccessCase{
				DecoderName:   decoderName(encoding.WireFormat),
				Name:          testCaseName(decodeSuccess.Name, encoding.WireFormat),
				Value:         valueStr,
				ValueType:     valueType,
				Bytes:         buildBytes(encoding.Bytes),
				HandleDefs:    buildHandleDefs(decodeSuccess.HandleDefs),
				Handles:       toDartIntList(encoding.Handles),
				UnusedHandles: toDartIntList(gidlir.GetUnusedHandles(decodeSuccess.Value, encoding.Handles)),
			})
		}
	}
	return decodeSuccessCases, nil
}

func encodeFailureCases(gidlEncodeFailures []gidlir.EncodeFailure, schema gidlmixer.Schema) ([]encodeFailureCase, error) {
	var encodeFailureCases []encodeFailureCase
	for _, encodeFailure := range gidlEncodeFailures {
		decl, err := schema.ExtractDeclarationUnsafe(encodeFailure.Value)
		if err != nil {
			return nil, fmt.Errorf("encode failure %s: %s", encodeFailure.Name, err)
		}
		if gidlir.ContainsUnknownField(encodeFailure.Value) {
			continue
		}
		errorCode, err := dartErrorCode(encodeFailure.Err)
		if err != nil {
			return nil, fmt.Errorf("encode failure %s: %s", encodeFailure.Name, err)
		}
		valueStr := visit(encodeFailure.Value, decl)
		valueType := typeName(decl)
		for _, wireFormat := range encodeFailure.WireFormats {
			if !wireFormatSupported(wireFormat) {
				continue
			}
			encodeFailureCases = append(encodeFailureCases, encodeFailureCase{
				EncoderName: encoderName(wireFormat),
				Name:        testCaseName(encodeFailure.Name, wireFormat),
				Value:       valueStr,
				ValueType:   valueType,
				ErrorCode:   errorCode,
				HandleDefs:  buildHandleDefs(encodeFailure.HandleDefs),
			})
		}
	}
	return encodeFailureCases, nil
}

func decodeFailureCases(gidlDecodeFailures []gidlir.DecodeFailure, schema gidlmixer.Schema) ([]decodeFailureCase, error) {
	var decodeFailureCases []decodeFailureCase
	for _, decodeFailure := range gidlDecodeFailures {
		_, err := schema.ExtractDeclarationByName(decodeFailure.Type)
		if err != nil {
			return nil, fmt.Errorf("decode failure %s: %s", decodeFailure.Name, err)
		}
		errorCode, err := dartErrorCode(decodeFailure.Err)
		if err != nil {
			return nil, fmt.Errorf("decode failure %s: %s", decodeFailure.Name, err)
		}
		valueType := dartTypeName(decodeFailure.Type)
		for _, encoding := range decodeFailure.Encodings {
			if !wireFormatSupported(encoding.WireFormat) {
				continue
			}
			decodeFailureCases = append(decodeFailureCases, decodeFailureCase{
				DecoderName: decoderName(encoding.WireFormat),
				Name:        testCaseName(decodeFailure.Name, encoding.WireFormat),
				ValueType:   valueType,
				Bytes:       buildBytes(encoding.Bytes),
				ErrorCode:   errorCode,
				HandleDefs:  buildHandleDefs(decodeFailure.HandleDefs),
				Handles:     toDartIntList(encoding.Handles),
			})
		}
	}
	return decodeFailureCases, nil
}

func wireFormatSupported(wireFormat gidlir.WireFormat) bool {
	return wireFormat == gidlir.V1WireFormat
}

func testCaseName(baseName string, wireFormat gidlir.WireFormat) string {
	return fidl.SingleQuote(fmt.Sprintf("%s_%s", baseName, wireFormat))
}

func encoderName(wireFormat gidlir.WireFormat) string {
	return fmt.Sprintf("Encoders.%s", wireFormat)
}

func decoderName(wireFormat gidlir.WireFormat) string {
	return fmt.Sprintf("Decoders.%s", wireFormat)
}

func dartTypeName(inputType string) string {
	return fmt.Sprintf("k%s_Type", inputType)
}

func buildBytes(bytes []byte) string {
	var builder strings.Builder
	builder.WriteString("Uint8List.fromList([\n")
	for i, b := range bytes {
		builder.WriteString(fmt.Sprintf("0x%02x,", b))
		if i%8 == 7 {
			// Note: empty comments are written to preserve formatting. See:
			// https://github.com/dart-lang/dart_style/wiki/FAQ#why-does-the-formatter-mess-up-my-collection-literals
			builder.WriteString(" //\n")
		}
	}
	builder.WriteString("])")
	return builder.String()
}

func toDartStr(value string) string {
	var buf bytes.Buffer
	buf.WriteRune('\'')
	for _, r := range value {
		if 0x20 <= r && r <= 0x7e { // printable ASCII rune
			buf.WriteRune(r)
		} else {
			buf.WriteString(fmt.Sprintf(`\u{%x}`, r))
		}
	}
	buf.WriteRune('\'')
	return buf.String()
}

func toDartIntList(handles []gidlir.Handle) string {
	var builder strings.Builder
	builder.WriteString("[\n")
	for i, handle := range handles {
		builder.WriteString(fmt.Sprintf("%d,", handle))
		if i%8 == 7 {
			// Note: empty comments are written to preserve formatting. See:
			// https://github.com/dart-lang/dart_style/wiki/FAQ#why-does-the-formatter-mess-up-my-collection-literals
			builder.WriteString(" //\n")
		}
	}
	builder.WriteString("]")
	return builder.String()
}

// Dart error codes defined in: topaz/public/dart/fidl/lib/src/error.dart.
var dartErrorCodeNames = map[gidlir.ErrorCode]string{
	gidlir.StringTooLong:              "fidlStringTooLong",
	gidlir.StringNotUtf8:              "unknown",
	gidlir.NonEmptyStringWithNullBody: "fidlNonEmptyStringWithNullBody",
	gidlir.StrictUnionFieldNotSet:     "fidlStrictXUnionFieldNotSet",
	gidlir.StrictUnionUnknownField:    "fidlStrictXUnionUnknownField",
	gidlir.StrictBitsUnknownBit:       "fidlInvalidBit",
	gidlir.StrictEnumUnknownValue:     "fidlInvalidEnumValue",
	gidlir.InvalidPaddingByte:         "unknown",
	gidlir.TooFewHandles:              "fidlTooFewHandles",
	gidlir.NonResourceUnknownHandles:  "fidlNonResourceHandle",
}

func dartErrorCode(code gidlir.ErrorCode) (string, error) {
	if str, ok := dartErrorCodeNames[code]; ok {
		return fmt.Sprintf("fidl.FidlErrorCode.%s", str), nil
	}
	return "", fmt.Errorf("no dart error string defined for error code %s", code)
}
