// 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.
//
// WARNING: This file is machine generated by fidlgen.

library fidl_test_name;

import 'dart:async';
import 'dart:developer';
import 'dart:typed_data';

import 'package:fidl/fidl.dart' as $fidl;
import 'package:meta/meta.dart';
import 'package:zircon/zircon.dart';

// These imports improve deduplication by making uses of {fidl.dart},
// {fidl_async.dart} and {fidl.dart, fidl_async.dart} generate equivalent
// packages. In AOT, the dead code will be removed by tree shaking.
// ignore: unused_import
import 'fidl_async.dart' as $strongly_connect_async;

// ignore_for_file: always_specify_types
// ignore_for_file: avoid_positional_boolean_parameters
// ignore_for_file: avoid_returning_null
// ignore_for_file: cascade_invocations
// ignore_for_file: constant_identifier_names
// ignore_for_file: one_member_abstracts
// ignore_for_file: prefer_constructors_over_static_methods
// ignore_for_file: prefer_single_quotes
// ignore_for_file: public_member_api_docs
// ignore_for_file: unused_import
// ignore_for_file: unused_local_variable
// ignore_for_file: non_constant_identifier_names
// ignore_for_file: library_prefixes
// ignore_for_file: prefer_typing_uninitialized_variables
// ignore_for_file: avoid_js_rounded_ints
// ignore_for_file: unnecessary_parenthesis
// ignore_for_file: always_put_required_named_parameters_first
// ignore_for_file: prefer_generic_function_type_aliases
// ignore_for_file: prefer_equal_for_default_values

/// const comment #1
///
/// const comment #3
const int c = 4;

enum UnionTag {
  field,
}

/// union comment #1
///
/// union comment #3
class Union extends $fidl.Union {
  const Union.withField(int value)
      : _data = value,
        tag = UnionTag.field;

  Union._(this.tag, Object data) : _data = data;

  final UnionTag tag;
  final _data;
  int get field {
    if (tag != UnionTag.field) {
      return null;
    }
    return _data;
  }

  @override
  String toString() {
    switch (tag) {
      case UnionTag.field:
        return 'Union.field($field)';
      default:
        return null;
    }
  }

  /// union comment #1
  ///
  /// union comment #3
  @override
  int get $index => tag.index;

  @override
  Object get $data => _data;

  static Union _ctor(int index, Object data) {
    return new Union._(UnionTag.values[index], data);
  }
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.UnionType<Union> kUnion_Type = const $fidl.UnionType<Union>(
  encodedSize: 8,
  members: const <$fidl.MemberType>[
    const $fidl.MemberType<int>(type: const $fidl.Int32Type(), offset: 4),
  ],
  ctor: Union._ctor,
);

/// struct comment #1
///
/// struct comment #3
class Struct extends $fidl.Struct {
  const Struct({
    @required this.field,
  });
  Struct.clone(
    Struct $orig, {
    int field,
  }) : this(
          field: field ?? $orig.field,
        );

  Struct._(List<Object> argv) : field = argv[0];

  /// struct member comment #1
  ///
  /// struct member comment #3
  final int field;

  @override
  List<Object> get $fields {
    return <Object>[
      field,
    ];
  }

  @override
  String toString() {
    // ignore: prefer_interpolation_to_compose_strings
    return r'Struct' r'(field: ' + field.toString() + r')';
  }

  static Struct _ctor(List<Object> argv) => new Struct._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.StructType<Struct> kStruct_Type = const $fidl.StructType<Struct>(
  encodedSize: 4,
  members: const <$fidl.MemberType>[
    const $fidl.MemberType<int>(type: const $fidl.Int32Type(), offset: 0),
  ],
  ctor: Struct._ctor,
);

/// table comment #1
///
/// table comment #3
class Table extends $fidl.Table {
  const Table({
    this.field,
  });

  Table._(Map<int, dynamic> argv) : field = argv[1];

  /// table field comment #1
  ///
  /// table field comment #3
  final int field;

  @override
  Map<int, dynamic> get $fields {
    return {
      1: field,
    };
  }

  static Table _ctor(Map<int, dynamic> argv) => new Table._(argv);
}

// See FIDL-308:
// ignore: recursive_compile_time_constant
const $fidl.TableType<Table> kTable_Type = const $fidl.TableType<Table>(
  encodedSize: 16,
  members: const <int, $fidl.FidlType>{
    1: const $fidl.Int32Type(),
  },
  ctor: Table._ctor,
);

abstract class Interface {
  static const String $serviceName = null;
  void method();
}

// method: ()
const int _kInterface_Method_Ordinal = 1061382220;
const $fidl.MethodType _kInterface_Method_Type = const $fidl.MethodType(
  request: null,
  response: null,
  name: r"Interface.Method",
);

class InterfaceProxy extends $fidl.Proxy<Interface> implements Interface {
  InterfaceProxy()
      : super(new $fidl.ProxyController<Interface>(
            $serviceName: null, $interfaceName: r'Interface')) {
    ctrl.onResponse = _handleResponse;
  }

  void _handleEvent($fidl.Message $message) {
    final $fidl.Decoder $decoder = new $fidl.Decoder($message);
    switch ($message.ordinal) {
      default:
        ctrl.proxyError('Unexpected message ordinal: ${$message.ordinal}');
        ctrl.close();
        break;
    }
  }

  void _handleResponse($fidl.Message $message) {
    final int $txid = $message.txid;
    if ($txid == 0) {
      _handleEvent($message);
      return;
    }
    final Function $callback = ctrl.getCallback($txid);
    if ($callback == null) {
      $message.closeHandles();
      return;
    }
    final $fidl.Decoder $decoder = new $fidl.Decoder($message);
    switch ($message.ordinal) {
      default:
        ctrl.proxyError('Unexpected message ordinal: ${$message.ordinal}');
        ctrl.close();
        break;
    }
  }

  @override
  void method() {
    if (!ctrl.isBound) {
      ctrl.proxyError('The proxy is closed.');
      return;
    }

    final $fidl.Encoder $encoder = new $fidl.Encoder();
    $encoder.encodeMessageHeader(_kInterface_Method_Ordinal, 0);
    ctrl.sendMessage($encoder.message);
  }
}

class InterfaceBinding extends $fidl.Binding<Interface> {
  @override
  void handleMessage($fidl.Message $message, $fidl.MessageSink $respond) {
    final $fidl.Decoder $decoder = new $fidl.Decoder($message);
    switch ($message.ordinal) {
      case _kInterface_Method_Ordinal:
        final String _name = _kInterface_Method_Type.name;
        try {
          Timeline.startSync(_name);
          final List<$fidl.MemberType> $types = _kInterface_Method_Type.request;
          $decoder.claimMemory(16);
          impl.method();
          // ignore: avoid_catches_without_on_clauses
        } catch (_e) {
          close();
          print('Exception handling method call $_name: $_e');
          rethrow;
        } finally {
          Timeline.finishSync();
        }
        break;
      default:
        throw new $fidl.FidlError(
            'Unexpected message name for InterfaceBinding');
    }
  }
}
