// import 'dart:convert';
// import 'dart:io';
//
// import 'package:analyzer/dart/element/element.dart';
// import 'package:build/build.dart';
// import 'package:code_builder/code_builder.dart';
// import 'package:dart_style/dart_style.dart';
// import 'package:guru_spec/guru_spec.dart';
// import 'package:source_gen/source_gen.dart';
// import 'package:yaml/yaml.dart';
//
// /// Created by Haoyi on 2022/5/26
//
// Builder generatorFactoryBuilder(BuilderOptions options) =>
//     SharedPartBuilder([GuruSpecGenerator()], "guru_spec");
//
// class FieldProcessor {
//   final dynamic _annotationType;
//   final List<String> _validTypeNames;
//   final Code Function(FieldElement element, ConstantReader annotation) assigner;
//
//   FieldProcessor(this._annotationType, this._validTypeNames, this.assigner);
// }
//
// class GuruSpecGenerator extends GeneratorForAnnotation<GuruSpec> {
//   static const flavorField = "flavor";
//
//   @override
//   generateForAnnotatedElement(Element element, ConstantReader annotation, BuildStep buildStep) {
//     if (element is! ClassElement) {
//       final name = element.displayName;
//       final todo = 'Remove the [GuruSpec] annotation from `$name`.';
//       throw InvalidGenerationSourceError(
//         'Generator cannot target `$name`.\n[TODO] $todo',
//         todo: 'Remove the [GuruSpec] annotation from `$name`.',
//       );
//     }
//     if (!element.isAbstract) {
//       final name = element.displayName;
//       final todo = 'Please change class [$name] to `abstract` class.';
//       throw InvalidGenerationSourceError(
//         'Generator cannot target `$name`.\n[TODO] $todo',
//         todo: todo,
//       );
//     }
//     bool isAppSpec = false;
//     for (var type in element.allSupertypes) {
//       if (type.getDisplayString(withNullability: false) == "AppSpec") {
//         isAppSpec = true;
//         break;
//       }
//     }
//     if (!isAppSpec) {
//       final name = element.displayName;
//       const todo = 'Please inherit the `AppSpec` class.';
//       throw InvalidGenerationSourceError(
//         'Generator cannot target `$name`.\n[TODO] $todo',
//         todo: todo,
//       );
//     }
//     return _implementClass(element, annotation);
//   }
//
//   String _implementClass(ClassElement element, ConstantReader annotation) {
//     log.info("_implementClass methods:${element.fields.map((e) => e.name)}");
//
//     String specName = "guru_spec.yaml";
//     final flavor = annotation.peek(flavorField)?.stringValue ?? "";
//     if (flavor.isNotEmpty) {
//       specName = "flavors/$flavor/guru_spec.yaml";
//     }
//     final guruSpecFile = File(specName);
//     if (!guruSpecFile.existsSync()) {
//       final name = element.displayName;
//       const todo = 'Not Found guru_spec.yaml File';
//       throw InvalidGenerationSourceError(
//         'Generator cannot target `$name`.\n[TODO] $todo',
//         todo: todo,
//       );
//     }
//     final yaml = guruSpecFile.readAsStringSync();
//     final jsonStr = json.encode(loadYaml(yaml));
//     final yamlMap = json.decode(jsonStr);
//
//     log.info("doc:$yamlMap");
//
//     final className = element.name;
//
//     final classBuilder = Class((clazz) {
//       clazz
//         ..name = '_$className'
//         ..constructors.add(buildAppSpecConstructor())
//         ..fields.addAll([
//           Field((field) => field
//             ..name = "instance"
//             ..static = true
//             ..assignment = Code("_$className._()")
//             ..modifier = FieldModifier.final$),
//           _buildAppName(yamlMap['app_name']),
//           _buildAppDetails(yamlMap['details']),
//           _buildDeployment(yamlMap['deployment']),
//           _buildAdsProfile(yamlMap['ads_profile']),
//           _buildIapProfile(),
//           _buildAdjustProfile(yamlMap['adjust_profile'] ?? {}),
//           _buildDefaultRemoteConfig()
//         ])
//         ..extend = refer(className);
//     });
//     final emitter = DartEmitter();
//
//     final iapClassBuilder = buildIapProductIds(yamlMap['iap_profile'] ?? {});
//
//     final remoteConfigConstantsBuilder = buildRemoteConfigConstantsClass(yamlMap['remote_config']);
//
//     final StringBuffer codeString = StringBuffer();
//     codeString
//         .write(DartFormatter().format([remoteConfigConstantsBuilder.accept(emitter)].join('\n\n')));
//     codeString.write(DartFormatter().format([iapClassBuilder.accept(emitter)].join('\n\n')));
//     codeString.write(DartFormatter().format([classBuilder.accept(emitter)].join('\n\n')));
//     return codeString.toString();
//   }
//
//   Constructor buildAppSpecConstructor() => Constructor((c) => c..name = "_");
//
//   Field _buildAppName(String name) {
//     return Field((field) => field
//       ..name = "appName"
//       ..static = false
//       ..assignment = Code("'$name'")
//       ..annotations.add(const CodeExpression(Code('override')))
//       ..modifier = FieldModifier.final$);
//   }
//
//   static const _appDetailsFieldMapping = {
//     "saas_app_id": "saasAppId",
//     "authority": "authority",
//     "storage_prefix": "storagePrefix",
//     "default_cdn_prefix": "defaultCdnPrefix",
//     "android_gp_url": "androidGooglePlayUrl",
//     "ios_spp_store_url": "iosAppStoreUrl",
//     "policy_url": "policyUrl",
//     "terms_url": "termsUrl",
//     "email_url": "emailUrl",
//     "package_name": "packageName",
//     "bundle_id": "bundleId"
//   };
//
//   Field _buildAppDetails(Map<String, dynamic> detailsMap) {
//     final codeBlocks = <Code>[const Code("AppDetails(")];
//     for (var fieldEntry in _appDetailsFieldMapping.entries) {
//       final fieldName = _appDetailsFieldMapping[fieldEntry.key];
//       final fieldData = detailsMap[fieldEntry.key];
//       if (fieldName != null && fieldData != null) {
//         codeBlocks.add(Code("$fieldName: '$fieldData',"));
//       }
//     }
//     codeBlocks.add(const Code(")"));
//
//     return Field((field) => field
//       ..name = "details"
//       ..static = false
//       ..assignment = Block.of(codeBlocks)
//       ..annotations.add(const CodeExpression(Code('override')))
//       ..modifier = FieldModifier.final$);
//   }
//
//   static const _deploymentFieldMapping = {
//     "property_cache_size": "propertyCacheSize",
//     "enable_dithering": "enableDithering",
//     "disable_rewards_ads": "disableRewardsAds"
//   };
//
//   Field _buildDeployment(Map<String, dynamic>? deploymentMap) {
//     late List<Code> codeBlocks;
//     if (deploymentMap == null || deploymentMap.isEmpty) {
//       codeBlocks = <Code>[const Code("Deployment.fromJson({})")];
//     } else {
//       codeBlocks = <Code>[const Code("Deployment(")];
//       for (var fieldEntry in _deploymentFieldMapping.entries) {
//         final fieldName = _deploymentFieldMapping[fieldEntry.key];
//         final fieldData = deploymentMap[fieldEntry.key];
//         if (fieldName != null && fieldData != null) {
//           codeBlocks.add(Code("$fieldName: $fieldData,"));
//         }
//       }
//       codeBlocks.add(const Code(")"));
//     }
//
//     return Field((field) => field
//       ..name = "deployment"
//       ..static = false
//       ..assignment = Block.of(codeBlocks)
//       ..annotations.add(const CodeExpression(Code('override')))
//       ..modifier = FieldModifier.final$);
//   }
//
//   static const _adsProfileFieldMapping = {
//     "banner_ad_unit_id": "bannerId",
//     "interstitial_ad_unit_id": "interstitialId",
//     "rewards_ad_unit_id": "rewardsId",
//     "amz_app_id": "amazonAppId",
//     "banner_amz_slot_id": "amazonBannerSlotId",
//     "interstitial_amz_slot_id": "amazonInterstitialSlotId",
//   };
//
//   static const _adsIdsMapping = {
//     "banner_ad_unit_id": "AdUnitId",
//     "interstitial_ad_unit_id": "AdUnitId",
//     "rewards_ad_unit_id": "AdUnitId",
//     "amz_app_id": "AdAppId",
//     "banner_amz_slot_id": "AdSlotId",
//     "interstitial_amz_slot_id": "AdSlotId"
//   };
//
//   Field _buildAdsProfile(Map<String, dynamic>? map) {
//     late List<Code> codeBlocks = <Code>[const Code("AdsProfile(")];
//     if (map == null || map.isEmpty) {
//       codeBlocks = <Code>[const Code("AdsProfile.invalid")];
//     } else {
//       codeBlocks = <Code>[const Code("AdsProfile(")];
//       for (var fieldEntry in _adsProfileFieldMapping.entries) {
//         final fieldName = _adsProfileFieldMapping[fieldEntry.key];
//         final fieldType = _adsIdsMapping[fieldEntry.key];
//         final fieldData = map[fieldEntry.key];
//
//         if (fieldName != null && fieldType != null && fieldData != null) {
//           final android = fieldData['android'] ?? '';
//           final ios = fieldData['ios'] ?? '';
//           codeBlocks.add(Code("$fieldName: const $fieldType(android: '$android', ios: '$ios'),"));
//         }
//       }
//       codeBlocks.add(const Code(")"));
//     }
//
//     return Field((field) => field
//       ..name = "adsProfile"
//       ..static = false
//       ..assignment = Block.of(codeBlocks)
//       ..annotations.add(const CodeExpression(Code('override')))
//       ..modifier = FieldModifier.final$);
//   }
//
//   Field _buildIapProfile() {
//     final codeBlocks = <Code>[const Code("IapProfile(")];
//     codeBlocks.add(const Code("noAds: IapProductIds.noAds,"));
//     codeBlocks.add(const Code("oneOffChargeIapIds: IapProductIds.oneOffChargeIapIds,"));
//     codeBlocks.add(const Code("subscriptionsIapIds: IapProductIds.subscriptionsIapIds)"));
//
//     return Field((field) => field
//       ..name = "iapProfile"
//       ..static = false
//       ..assignment = Block.of(codeBlocks)
//       ..annotations.add(const CodeExpression(Code('override')))
//       ..modifier = FieldModifier.final$);
//   }
//
//   Field _buildDefaultRemoteConfig() {
//     return Field((field) => field
//       ..name = "defaultRemoteConfig"
//       ..static = false
//       ..assignment = const Code("RemoteConfigConstants._defaultConfigs")
//       ..annotations.add(const CodeExpression(Code('override')))
//       ..modifier = FieldModifier.final$);
//   }
//
//   Field _buildAdjustProfile(Map<String, dynamic> map) {
//     final codeBlocks = <Code>[const Code("AdjustProfile(")];
//     final appTokenMap = map['app_token'];
//     if (appTokenMap != null) {
//       codeBlocks.add(Code(
//           "appToken: Platform.isAndroid ? '${appTokenMap['android'] ?? ''}' : '${appTokenMap['ios'] ?? ''}',"));
//     } else {
//       codeBlocks.add(const Code("appToken: '',"));
//     }
//     final eventMap = map['event_map'] ?? {};
//
//     final androidMapCodeBlocks = <Code>[];
//     final iosMapCodeBlocks = <Code>[];
//
//     Code? generateCode(String event, dynamic token, bool revenue) {
//       if (token != null && token != '') {
//         if (revenue == true) {
//           return Code(
//               "\"$event\": (params)=> AdjustEvent(\"$token\")..setRevenue(params['revenue'] ?? 0.0, params['currency'] ?? ''),");
//         }
//         return Code("\"$event\": (_) => AdjustEvent(\"$token\"),");
//       }
//       return null;
//     }
//
//     if (eventMap is Map) {
//       for (var entry in eventMap.entries) {
//         final map = entry.value;
//         final androidToken = map['android'];
//         final iosToken = map['ios'];
//         final revenue = map['revenue'] == true;
//
//         final androidCode = generateCode(entry.key, androidToken, revenue);
//         if (androidCode != null) {
//           androidMapCodeBlocks.add(androidCode);
//         }
//
//         final iosCode = generateCode(entry.key, iosToken, revenue);
//         if (iosCode != null) {
//           iosMapCodeBlocks.add(iosCode);
//         }
//       }
//     }
//     codeBlocks
//         .add(const Code("eventNameMapping: Platform.isAndroid ? <String, AdjustEventConverter>{"));
//     codeBlocks.addAll(androidMapCodeBlocks);
//     codeBlocks.add(const Code("} : <String, AdjustEventConverter>{"));
//     codeBlocks.addAll(iosMapCodeBlocks);
//     codeBlocks.add(const Code("})"));
//
//     return Field((field) => field
//       ..name = "adjustProfile"
//       ..static = false
//       ..assignment = Block.of(codeBlocks)
//       ..annotations.add(const CodeExpression(Code('override')))
//       ..modifier = FieldModifier.final$);
//   }
//
//   static String camelCase(String value) {
//     if (value == '') {
//       return '';
//     }
//
//     final separatedWords = value.split(RegExp(r'[!@#<>?":`~;[\]\\|=+)(*&^%-\s_]+'));
//     var newString = '';
//
//     for (final word in separatedWords) {
//       newString += word[0].toUpperCase() + word.substring(1).toLowerCase();
//     }
//
//     return newString[0].toLowerCase() + newString.substring(1);
//   }
//
//   List<Field> _buildIapProductField(Map<String, dynamic> map) {
//     final List<Field> fieldList = <Field>[];
//     String? noAds;
//     final List<String> oneOffChargeIapIds = [];
//     final List<String> subscriptionsIapIds = [];
//     for (var fieldEntry in map.entries) {
//       String fieldName = camelCase(fieldEntry.key);
//       final fieldData = fieldEntry.value;
//       if (fieldName != '' && fieldData != null) {
//         final android = fieldData['android'] ?? '';
//         final ios = fieldData['ios'] ?? '';
//         final attr = fieldData['attr'] ?? '';
//
//         if (fieldEntry.key == 'no_ads') {
//           fieldName = '_$fieldName';
//           noAds = fieldName;
//         }
//
//         if (attr == 'subscriptions') {
//           subscriptionsIapIds.add(fieldName);
//         } else {
//           oneOffChargeIapIds.add(fieldName);
//         }
//
//         fieldList.add(Field((field) => field
//           ..name = fieldName
//           ..static = true
//           ..assignment =
//               Code("ProductId(android: '$android', ios: '$ios', attr: TransactionAttributes.$attr)")
//           ..modifier = FieldModifier.constant));
//       }
//     }
//
//     fieldList.add(Field((field) => field
//       ..name = "noAds"
//       ..static = true
//       ..type = refer("ProductId?")
//       ..assignment = Code(noAds ?? 'null')
//       ..modifier = FieldModifier.constant));
//
//     fieldList.add(Field((field) => field
//       ..name = "oneOffChargeIapIds"
//       ..static = true
//       ..assignment = Code("<ProductId>[${oneOffChargeIapIds.join(',')}]")
//       ..modifier = FieldModifier.constant));
//
//     fieldList.add(Field((field) => field
//       ..name = "subscriptionsIapIds"
//       ..static = true
//       ..assignment = Code("<ProductId>[${subscriptionsIapIds.join(',')}]")
//       ..modifier = FieldModifier.constant));
//
//     return fieldList;
//   }
//
//   List<Method> buildIapProfileMethods() {
//     final List<Method> methodList = <Method>[];
//     methodList.add(Method((method) => method
//       ..name = 'ids'
//       ..type = MethodType.getter
//       ..returns = refer('List<ProductId>')
//       ..lambda = true
//       ..body = const Code("[...oneOffChargeIapIds, ...subscriptionsIapIds]")
//       ..static = true));
//     return methodList;
//   }
//
//   Class buildIapProductIds(Map<String, dynamic> map) {
//     return Class((clazz) {
//       clazz
//         ..name = 'IapProductIds'
//         ..fields.addAll(_buildIapProductField(map))
//         ..methods.addAll(buildIapProfileMethods());
//       // ..methods.addAll([_buildCreator(element, blocks)])
//       // ..methods.addAll(designSpec.nestedSpec ? [] : [_buildGetter(element)])
//       // ..extend = refer(className);
//     });
//   }
//
//   Class buildRemoteConfigConstantsClass(Map<String, dynamic> map) {
//     final List<Field> fieldList = <Field>[];
//     final codeBlocks = <Code>[const Code("{")];
//     for (var fieldEntry in map.entries) {
//       final fieldName = camelCase(fieldEntry.key);
//       final fieldData = fieldEntry.value;
//       if (fieldName != '' && fieldData != null) {
//         fieldList.add(Field((field) => field
//           ..name = fieldName
//           ..static = true
//           ..assignment = Code("'${fieldEntry.key}'")
//           ..modifier = FieldModifier.constant));
//         codeBlocks.add(Code("$fieldName: '$fieldData',"));
//       }
//     }
//     codeBlocks.add(const Code("}"));
//
//     fieldList.add(Field((field) => field
//       ..name = '_defaultConfigs'
//       ..static = true
//       ..type = refer("Map<String, dynamic>")
//       ..assignment = Block.of(codeBlocks)
//       ..modifier = FieldModifier.constant));
//
//     final List<Method> methodList = <Method>[];
//     methodList.add(Method((method) => method
//       ..name = 'getDefaultConfigString'
//       ..returns = refer('String')
//       ..lambda = true
//       ..requiredParameters.addAll([
//         Parameter((p) => p
//           ..type = refer("String")
//           ..name = "key")
//       ])
//       ..body = const Code("_defaultConfigs[key]")
//       ..static = true));
//
//     return Class((clazz) {
//       clazz
//         ..name = 'RemoteConfigConstants'
//         ..fields.addAll(fieldList)
//         ..methods.addAll(methodList);
//       // ..methods.addAll([_buildCreator(element, blocks)])
//       // ..methods.addAll(designSpec.nestedSpec ? [] : [_buildGetter(element)])
//       // ..extend = refer(className);
//     });
//   }
//
// // => Field((field) => field
//
// }