using FlutterCodeGenerator.Helper; using System; using System.Collections.Generic; using System.Text; namespace FlutterCodeGenerator.ModelTypes { internal class ComplexModelType : ModelType { public List Children { get; set; } public ComplexModelType(Type type, string name) : base(type, name) { Children = new List(); } protected virtual string ToJson(List Children) { var source = new StringBuilder(); source.AppendLine("\tMap toJson() {"); source.AppendLine("\t\tfinal map = Map();"); foreach (var child in Children) { if (child is EnumModelType) { source.AppendLine($"\t\tmap['{child.Name_Upper}'] = {child.Name_Lower}.index;"); } else if (child is EnumNullableModelType) { source.AppendLine($"\t\tif ({child.Name_Lower} != null)"); source.AppendLine($"\t\tmap['{child.Name_Upper}'] = {child.Name_Lower}?.index;"); } else if (child.DefaultValue != null) { source.AppendLine($"\t\tmap['{child.Name_Upper}'] = {child.Name_Lower};"); } else if (child is DateTimeModelType) { source.AppendLine($"\t\tif ({child.Name_Lower} != null)"); source.AppendLine($"\t\t\tmap['{child.Name_Upper}'] = JsonRpcUtils.dateFormat({child.Name_Lower}!);"); } else if (child is ListModelType listModelType) { if (listModelType.GenericArgumentModelType is EnumModelType) { source.AppendLine($"\t\tif ({child.Name_Lower} != null) {{"); source.AppendLine($"\t\t\tList {child.Name_Lower}List = [];"); source.AppendLine($"\t\t\t{child.Name_Lower}!.forEach((e) => {child.Name_Lower}List.add(e.index));"); source.AppendLine($"\t\t\tmap['{child.Name_Upper}'] = {child.Name_Lower}List;"); source.AppendLine($"\t\t}}"); } else { source.AppendLine($"\t\tif ({child.Name_Lower} != null)"); source.AppendLine($"\t\t\tmap['{child.Name_Upper}'] = {child.Name_Lower};"); } } else { source.AppendLine($"\t\tif ({child.Name_Lower} != null)"); source.AppendLine($"\t\t\tmap['{child.Name_Upper}'] = {child.Name_Lower};"); } } source.AppendLine("\t\treturn map;"); source.AppendLine("\t}"); return source.ToString(); } protected virtual string FromJson(List Children) { var source = new StringBuilder(); string flutterTypeName = null; if (this is UserDefinedGenericModelType) { flutterTypeName = GetFlutterTypeName(false, false, true); } else { flutterTypeName = GetFlutterTypeName(); } source.AppendLine($"\tfactory {flutterTypeName}.fromJson(Map map) {{"); foreach (var child in Children) { if (child is ArrayModelType) { source.AppendLine($"\t\tfinal {child.Name_Lower}Data = map['{child.Name_Upper}'];"); } else if (child is ListModelType listModelType) { if (this is UserDefinedGenericModelType type) { if (type.GenericArgumentModelType.ParameterType == listModelType.GenericArgumentModelType.ParameterType) { source.AppendLine($"\t\tList {listModelType.Name_Lower}List = [];"); source.AppendLine($"\t\tif (map['{listModelType.Name_Upper}'] != null) {{"); source.AppendLine($"\t\t\t{listModelType.Name_Lower}List.addAll("); source.AppendLine($"\t\t\t\t\t(map['{listModelType.Name_Upper}'] as List).map((e) => FJsonConvert.fromJson(e)!));"); source.AppendLine($"\t\t}}"); } } else if (this is UserDefinedDerivedModelType derivedModelType && derivedModelType.BaseType is UserDefinedGenericModelType baseType) { if (baseType.GenericArgumentModelType.ParameterType == listModelType.GenericArgumentModelType.ParameterType) { source.AppendLine($"\t\tList<{listModelType.GenericArgumentModelType.GetFlutterTypeName()}> {listModelType.Name_Lower}List = [];"); source.AppendLine($"\t\tif (map['{listModelType.Name_Upper}'] != null) {{"); source.AppendLine($"\t\t\t{listModelType.Name_Lower}List.addAll("); source.AppendLine($"\t\t\t\t\t(map['{listModelType.Name_Upper}'] as List).map((e) => FJsonConvert.fromJson<{listModelType.GenericArgumentModelType.GetFlutterTypeName()}>(e)!));"); source.AppendLine($"\t\t}}"); } } } else if (child is UserDefinedGenericModelType userDefinedGenericComplexModelType) { if (this is UserDefinedGenericModelType type) { if (type.GenericArgumentModelType.ParameterType == userDefinedGenericComplexModelType.GenericArgumentModelType.ParameterType) { source.AppendLine($"\t\tList {userDefinedGenericComplexModelType.Name_Lower}List = [];"); source.AppendLine($"\t\tif (map['{userDefinedGenericComplexModelType.Name_Upper}'] != null) {{"); source.AppendLine($"\t\t\t{userDefinedGenericComplexModelType.Name_Lower}List.addAll("); source.AppendLine($"\t\t\t\t\t(map['{userDefinedGenericComplexModelType.Name_Upper}'] as List).map((e) => FJsonConvert.fromJson(e)!));"); source.AppendLine($"\t\t}}"); } else if (this is UserDefinedDerivedModelType derivedModelType && derivedModelType.BaseType is UserDefinedGenericModelType baseType) { if (baseType.GenericArgumentModelType.ParameterType == userDefinedGenericComplexModelType.GenericArgumentModelType.ParameterType) { source.AppendLine($"\t\tList<{userDefinedGenericComplexModelType.GenericArgumentModelType.ParameterType}> {userDefinedGenericComplexModelType.Name_Lower}List = [];"); source.AppendLine($"\t\tif (map['{userDefinedGenericComplexModelType.Name_Upper}'] != null) {{"); source.AppendLine($"\t\t\t{userDefinedGenericComplexModelType.Name_Lower}List.addAll("); source.AppendLine($"\t\t\t\t\t(map['{userDefinedGenericComplexModelType.Name_Upper}'] as List).map((e) => FJsonConvert.fromJson<{userDefinedGenericComplexModelType.GenericArgumentModelType.ParameterType}>(e)!));"); source.AppendLine($"\t\t}}"); } } } } else if (child is DictionaryModelType dictionaryModelType) { var argumentName1 = dictionaryModelType.GenericArgumentModelTypeList[0].GetFlutterTypeName(); var argumentName2 = dictionaryModelType.GenericArgumentModelTypeList[1].GetFlutterTypeName(); if (dictionaryModelType.GenericArgumentModelTypeList[0] is SimpleModelType && dictionaryModelType.GenericArgumentModelTypeList[1] is SimpleModelType) { } else { source.AppendLine($"\t\tfinal {child.Name_Lower}Map= <{argumentName1},{argumentName2}>{{}};"); source.AppendLine($"\t\tfor (var key in map['{child.Name_Upper}'].keys) {{"); source.AppendLine($"\t\t\t{child.Name_Lower}Map[key] = {argumentName2}.fromJson(map['{child.Name_Upper}'][key]);"); source.AppendLine($"\t\t}}"); } } } source.AppendLine($"\t\treturn {flutterTypeName}( "); foreach (var child in Children) { if (child is EnumModelType) { source.AppendLine($"\t\t\t{child.Name_Lower}: {child.GetFlutterTypeName()}.values.firstWhere((e) => e.index == map['{child.Name_Upper}']),"); } else if (child is EnumNullableModelType) { source.AppendLine($"\t\t\t{child.Name_Lower}: map['{child.Name_Upper}'] != null ? {child.GetFlutterTypeName()}.values.firstWhere((e) => e.index == map['{child.Name_Upper}']) : null,"); } else if (child is ArrayModelType) { var arrayTypeName = child.ParameterType.FullName.Replace("[]", string.Empty); var arrayType = child.ParameterType.Assembly.GetType(arrayTypeName); var modelType = ModelTypeGenerator.Create(arrayType, ""); if (modelType is ByteModelType) { source.AppendLine($"\t\t\t{child.Name_Lower}: {child.Name_Lower}Data != null ? ({child.Name_Lower}Data as List).map((e) => e as int).toList(): null,"); } else if (modelType is SimpleModelType && (modelType is ExtraObjectModelType)) { source.AppendLine($"\t\t\t{child.Name_Lower}: {child.Name_Lower}Data != null ? ({child.Name_Lower}Data as List).map((e) => e as {child.ParameterType.Name.Replace("[]", string.Empty)}).toList(): null,"); } else if (modelType is SimpleModelType) { source.AppendLine($"\t\t\t{child.Name_Lower}: map['{child.Name_Lower}']?.cast<{child.ParameterType.Name.Replace("[]", string.Empty)}>().toList(),"); } else { source.AppendLine($"\t\t\t{child.Name_Lower}: {child.Name_Lower}Data != null ? ({child.Name_Lower}Data as List).map((e) => {child.ParameterType.Name.Replace("[]", string.Empty)}.fromJson(e)).toList(): null,"); } } else if (child is DateTimeModelType) { source.AppendLine($"\t\t\t{child.Name_Lower}: map['{child.Name_Upper}'] != null ? DateTime.parse(map['{child.Name_Upper}']) : null,"); } else if (child is ListModelType listModelType) { if (this is UserDefinedGenericModelType type) { if (type.GenericArgumentModelType.ParameterType == listModelType.GenericArgumentModelType.ParameterType) { source.AppendLine($"\t\t\t{child.Name_Lower}: {listModelType.Name_Lower}List,"); } else if (listModelType.GenericArgumentModelType is SimpleModelType && !(listModelType.GenericArgumentModelType is ExtraObjectModelType)) { var model = listModelType.GenericArgumentModelType.GetFlutterTypeName(); source.AppendLine($"\t\t\t{child.Name_Lower}: map['{child.Name_Upper}']?.cast<{model}>().toList(),"); } else if (listModelType.GenericArgumentModelType is EnumModelType) { var model = listModelType.GenericArgumentModelType.GetFlutterTypeName(); source.AppendLine($"\t\t\t{child.Name_Lower}: map['{child.Name_Upper}'] != null ? (map['{child.Name_Upper}'] as List).map((e)=>{model}.values.firstWhere((i) => i.index == e)).toList() : null,"); } else { var model = listModelType.GenericArgumentModelType.GetFlutterTypeName(); source.AppendLine($"\t\t\t{child.Name_Lower}: map['{child.Name_Upper}'] != null ? (map['{child.Name_Upper}'] as List).map((e)=>{model}.fromJson(e as Map)).toList() : null,"); } } else if (this is UserDefinedDerivedModelType definedDerivedModelType && definedDerivedModelType.BaseType is UserDefinedGenericModelType baseType) { if (baseType.GenericArgumentModelType.ParameterType == listModelType.GenericArgumentModelType.ParameterType) { source.AppendLine($"\t\t\t{child.Name_Lower}: {listModelType.Name_Lower}List,"); } else if (listModelType.GenericArgumentModelType is SimpleModelType && !(listModelType.GenericArgumentModelType is ExtraObjectModelType)) { var model = listModelType.GenericArgumentModelType.GetFlutterTypeName(); source.AppendLine($"\t\t\t{child.Name_Lower}: map['{child.Name_Upper}']?.cast<{model}>().toList(),"); } else if (listModelType.GenericArgumentModelType is EnumModelType) { var model = listModelType.GenericArgumentModelType.GetFlutterTypeName(); source.AppendLine($"\t\t\t{child.Name_Lower}: map['{child.Name_Upper}'] != null ? (map['{child.Name_Upper}'] as List).map((e)=>{model}.values.firstWhere((i) => i.index == e)).toList() : null,"); } else { var model = listModelType.GenericArgumentModelType.GetFlutterTypeName(); source.AppendLine($"\t\t\t{child.Name_Lower}: map['{child.Name_Upper}'] != null ? (map['{child.Name_Upper}'] as List).map((e)=>{model}.fromJson(e as Map)).toList() : null,"); } } else if (this is UserDefinedModelType || this is UserDefinedDerivedModelType) { if (listModelType.GenericArgumentModelType is SimpleModelType && !(listModelType.GenericArgumentModelType is ExtraObjectModelType)) { var model = listModelType.GenericArgumentModelType.GetFlutterTypeName(); source.AppendLine($"\t\t\t{child.Name_Lower}: map['{child.Name_Upper}']?.cast<{model}>().toList(),"); } else if (listModelType.GenericArgumentModelType is EnumModelType) { var model = listModelType.GenericArgumentModelType.GetFlutterTypeName(); source.AppendLine($"\t\t\t{child.Name_Lower}: map['{child.Name_Upper}'] != null ? (map['{child.Name_Upper}'] as List).map((e)=>{model}.values.firstWhere((i) => i.index == e)).toList() : null,"); } else { var model = listModelType.GenericArgumentModelType.GetFlutterTypeName(); source.AppendLine($"\t\t\t{child.Name_Lower}: map['{child.Name_Upper}'] != null ? (map['{child.Name_Upper}'] as List).map((e)=>{model}.fromJson(e as Map)).toList() : null,"); } } } else if (child is DictionaryModelType dictionaryModelType) { var argumentName1 = dictionaryModelType.GenericArgumentModelTypeList[0].GetFlutterTypeName(); var argumentName2 = dictionaryModelType.GenericArgumentModelTypeList[1].GetFlutterTypeName(); if(dictionaryModelType.GenericArgumentModelTypeList[0] is SimpleModelType && dictionaryModelType.GenericArgumentModelTypeList[1] is SimpleModelType) { source.AppendLine($"\t\t\t{child.Name_Lower}: map['{child.Name_Upper}']?.cast<{argumentName1},{argumentName2}>(),"); } else { source.AppendLine($"\t\t\t {child.Name_Lower} : {child.Name_Lower}Map"); } } else if (child is UserDefinedGenericModelType userDefinedGenericModelType) { if (this is UserDefinedGenericModelType type) { if (type.GenericArgumentModelType.ParameterType == userDefinedGenericModelType.GenericArgumentModelType.ParameterType) { source.AppendLine($"\t\t\t{child.Name_Lower}: {userDefinedGenericModelType.Name_Lower}List,"); } else if (userDefinedGenericModelType.GenericArgumentModelType is SimpleModelType && !(userDefinedGenericModelType.GenericArgumentModelType is ExtraObjectModelType)) { var model = userDefinedGenericModelType.GenericArgumentModelType.GetFlutterTypeName(); source.AppendLine($"\t\t\t{child.Name_Lower}: map['{child.Name_Upper}']?.cast<{model}>().toList(),"); } else if (userDefinedGenericModelType.GenericArgumentModelType is EnumModelType) { var model = userDefinedGenericModelType.GenericArgumentModelType.GetFlutterTypeName(); source.AppendLine($"\t\t\t{child.Name_Lower}: map['{child.Name_Upper}'] != null ? (map['{child.Name_Upper}'] as List).map((e)=>{model}.values.firstWhere((i) => i.index == e)).toList() : null,"); } else { var model = userDefinedGenericModelType.GenericArgumentModelType.GetFlutterTypeName(); source.AppendLine($"\t\t\t{child.Name_Lower}: map['{child.Name_Upper}'] != null ? (map['{child.Name_Upper}'] as List).map((e)=>{model}.fromJson(e as Map)).toList() : null,"); } } else if (this is UserDefinedModelType) { if (userDefinedGenericModelType.GenericArgumentModelType is SimpleModelType && !(userDefinedGenericModelType.GenericArgumentModelType is ExtraObjectModelType)) { var model = userDefinedGenericModelType.GenericArgumentModelType.GetFlutterTypeName(); source.AppendLine($"\t\t\t{child.Name_Lower}: map['{child.Name_Upper}']?.cast<{model}>().toList(),"); } else if (userDefinedGenericModelType.GenericArgumentModelType is EnumModelType) { var model = userDefinedGenericModelType.GenericArgumentModelType.GetFlutterTypeName(); source.AppendLine($"\t\t\t{child.Name_Lower}: map['{child.Name_Upper}'] != null ? (map['{child.Name_Upper}'] as List).map((e)=>{model}.values.firstWhere((i) => i.index == e)).toList() : null,"); } else { var model = userDefinedGenericModelType.GetFlutterTypeName(); source.AppendLine($"\t\t\t{child.Name_Lower}: map['{child.Name_Upper}'] != null ? {model}.fromJson(map['{child.Name_Upper}'] as Map) : null,"); } } } else if (child is UserDefinedModelType || child is UserDefinedDerivedModelType || child is ExtraObjectModelType) { source.AppendLine($"\t\t\t{child.Name_Lower}: map['{child.Name_Upper}'] != null ? {child.GetFlutterTypeName()}.fromJson(map['{child.Name_Upper}']) : null,"); } else if (child is DoubleModelType) { source.AppendLine($"\t\t\t{child.Name_Lower}: double.parse(map['{child.Name_Upper}'].toString()),"); } else { source.AppendLine($"\t\t\t{child.Name_Lower}: map['{child.Name_Upper}'],"); } } source.AppendLine("\t\t);"); source.AppendLine("\t}"); source.AppendLine(); return source.ToString(); } } }