#!/usr/bin/env bash

set -o errexit -o nounset

safe-xargs() { perl -p -e "s/\n/\0/;" | xargs -0 "$@" ; }

use-comby() {
  find src/wab -name '*.ts' -o -name '*.tsx' | fgrep -v /plasmic/ | safe-xargs comby -timeout 9 -in-place ':[x] instanceof :[y~\b(Num|Text|DateTime|Id|Bool|Img|Binary|Any|Collection|MapType|Optional|Union|Choice|ComponentInstance|PlumeInstance|QueryData|VariantedValue|StyleToken|BlobRef|HostLessPackageInfo|ProjectDepLocalResource|SiteFolder|Site|ArenaFrameGrid|ArenaFrameRow|ArenaFrameCell|ComponentArena|PageArena|Arena|FocusedFrameArena|ArenaChild|ArenaFrame|OpaqueType|StyleNode|RuleSet|Rule|VariantedRuleSet|Mixin|Theme|ThemeStyle|LocalPresets|ProjectDependency|ImageAsset|TplTag|TplComponent|TplSlot|TplGroup|ColumnsSetting|Preset|PresetGroup|PageMeta|ComponentDataQuery|CodeComponentMeta|Component|Query|RestQuery|FetcherQuery|GraphqlQuery|NameArg|PlumeInfo|Variant|VariantGroup|ComponentVariantGroup|VariantSetting|EventHandler|Interaction|ColumnsConfig|Marker|StyleMarker|NodeMarker|RawText|ExprText|ExprBinding|Var|Cell|Rep|Let|Param|Arg|RenderExpr|VirtualRenderExpr|CustomCode|DataSourceOpExpr|DataSourceTemplate|VarRef|ImageAssetRef|PageHref|VariantsRef|SimplePath|ObjectPath|State|Split|SplitSlice|RandomSplitSlice|SegmentSplitSlice|SplitContent|GlobalVariantSplitContent|ComponentVariantSplitContent|ComponentSwapSplitContent|Type|Scalar|Num|Text|DateTime|Id|Bool|Img|Binary|Any|Collection|MapType|Optional|Union|Choice|ComponentInstance|PlumeInstance|UserType|QueryData|VariantedValue|StyleToken|BlobRef|HostLessPackageInfo|ProjectDepLocalResource|SiteFolder|Site|ArenaFrameGrid|ArenaFrameRow|ArenaFrameCell|ComponentArena|PageArena|Arena|FocusedFrameArena|ArenaChild|ArenaFrame|OpaqueType|StyleNode|RuleSet|Rule|VariantedRuleSet|Mixin|Theme|ThemeStyle|LocalPresets|ProjectDependency|ImageAsset|TplNode|TplTag|TplComponent|TplSlot|TplGroup|ColumnsSetting|Preset|PresetGroup|PageMeta|ComponentDataQuery|CodeComponentMeta|Component|Query|RestQuery|FetcherQuery|GraphqlQuery|NameArg|PlumeInfo|Variant|VariantGroup|ComponentVariantGroup|VariantSetting|EventHandler|Interaction|ColumnsConfig|Marker|StyleMarker|NodeMarker|RichText|RawText|ExprText|ExprBinding|Var|Cell|BindingStruct|Rep|Let|Param|Arg|Expr|RenderExpr|VirtualRenderExpr|CustomCode|DataSourceOpExpr|DataSourceTemplate|VarRef|ImageAssetRef|PageHref|VariantsRef|SimplePath|ObjectPath|State|Split|SplitSlice|RandomSplitSlice|SegmentSplitSlice|SplitContent|GlobalVariantSplitContent|ComponentVariantSplitContent|ComponentSwapSplitContent)\b]' 'isClean:[y](:[x])'
  find src/wab -name '*.ts' -o -name '*.tsx' | fgrep -v /plasmic/ | safe-xargs comby -timeout 9 -in-place 'ensureInstance(:[x], :[y~\b(Num|Text|DateTime|Id|Bool|Img|Binary|Any|Collection|MapType|Optional|Union|Choice|ComponentInstance|PlumeInstance|QueryData|VariantedValue|StyleToken|BlobRef|HostLessPackageInfo|ProjectDepLocalResource|SiteFolder|Site|ArenaFrameGrid|ArenaFrameRow|ArenaFrameCell|ComponentArena|PageArena|Arena|FocusedFrameArena|ArenaChild|ArenaFrame|OpaqueType|StyleNode|RuleSet|Rule|VariantedRuleSet|Mixin|Theme|ThemeStyle|LocalPresets|ProjectDependency|ImageAsset|TplTag|TplComponent|TplSlot|TplGroup|ColumnsSetting|Preset|PresetGroup|PageMeta|ComponentDataQuery|CodeComponentMeta|Component|Query|RestQuery|FetcherQuery|GraphqlQuery|NameArg|PlumeInfo|Variant|VariantGroup|ComponentVariantGroup|VariantSetting|EventHandler|Interaction|ColumnsConfig|Marker|StyleMarker|NodeMarker|RawText|ExprText|ExprBinding|Var|Cell|Rep|Let|Param|Arg|RenderExpr|VirtualRenderExpr|CustomCode|DataSourceOpExpr|DataSourceTemplate|VarRef|ImageAssetRef|PageHref|VariantsRef|SimplePath|ObjectPath|State|Split|SplitSlice|RandomSplitSlice|SegmentSplitSlice|SplitContent|GlobalVariantSplitContent|ComponentVariantSplitContent|ComponentSwapSplitContent|Type|Scalar|Num|Text|DateTime|Id|Bool|Img|Binary|Any|Collection|MapType|Optional|Union|Choice|ComponentInstance|PlumeInstance|UserType|QueryData|VariantedValue|StyleToken|BlobRef|HostLessPackageInfo|ProjectDepLocalResource|SiteFolder|Site|ArenaFrameGrid|ArenaFrameRow|ArenaFrameCell|ComponentArena|PageArena|Arena|FocusedFrameArena|ArenaChild|ArenaFrame|OpaqueType|StyleNode|RuleSet|Rule|VariantedRuleSet|Mixin|Theme|ThemeStyle|LocalPresets|ProjectDependency|ImageAsset|TplNode|TplTag|TplComponent|TplSlot|TplGroup|ColumnsSetting|Preset|PresetGroup|PageMeta|ComponentDataQuery|CodeComponentMeta|Component|Query|RestQuery|FetcherQuery|GraphqlQuery|NameArg|PlumeInfo|Variant|VariantGroup|ComponentVariantGroup|VariantSetting|EventHandler|Interaction|ColumnsConfig|Marker|StyleMarker|NodeMarker|RichText|RawText|ExprText|ExprBinding|Var|Cell|BindingStruct|Rep|Let|Param|Arg|Expr|RenderExpr|VirtualRenderExpr|CustomCode|DataSourceOpExpr|DataSourceTemplate|VarRef|ImageAssetRef|PageHref|VariantsRef|SimplePath|ObjectPath|State|Split|SplitSlice|RandomSplitSlice|SegmentSplitSlice|SplitContent|GlobalVariantSplitContent|ComponentVariantSplitContent|ComponentSwapSplitContent)\b])' 'ensureClean:[y](:[x])'
}

use-semgrep() {
  cat > rule.yaml << "EOF"
rules:
- id: instanceof
  patterns:
    - pattern: $X instanceof $Y
    - metavariable-regex:
        metavariable: $Y
        regex: \b(Num|Text|DateTime|Id|Bool|Img|Binary|Any|Collection|MapType|Optional|Union|Choice|ComponentInstance|PlumeInstance|QueryData|VariantedValue|StyleToken|BlobRef|HostLessPackageInfo|ProjectDepLocalResource|SiteFolder|Site|ArenaFrameGrid|ArenaFrameRow|ArenaFrameCell|ComponentArena|PageArena|Arena|FocusedFrameArena|ArenaChild|ArenaFrame|OpaqueType|StyleNode|RuleSet|Rule|VariantedRuleSet|Mixin|Theme|ThemeStyle|LocalPresets|ProjectDependency|ImageAsset|TplTag|TplComponent|TplSlot|TplGroup|ColumnsSetting|Preset|PresetGroup|PageMeta|ComponentDataQuery|CodeComponentMeta|Component|Query|RestQuery|FetcherQuery|GraphqlQuery|NameArg|PlumeInfo|Variant|VariantGroup|ComponentVariantGroup|VariantSetting|EventHandler|Interaction|ColumnsConfig|Marker|StyleMarker|NodeMarker|RawText|ExprText|ExprBinding|Var|Cell|Rep|Let|Param|Arg|RenderExpr|VirtualRenderExpr|CustomCode|DataSourceOpExpr|DataSourceTemplate|VarRef|ImageAssetRef|PageHref|VariantsRef|SimplePath|ObjectPath|State|Split|SplitSlice|RandomSplitSlice|SegmentSplitSlice|SplitContent|GlobalVariantSplitContent|ComponentVariantSplitContent|ComponentSwapSplitContent|Type|Scalar|Num|Text|DateTime|Id|Bool|Img|Binary|Any|Collection|MapType|Optional|Union|Choice|ComponentInstance|PlumeInstance|UserType|QueryData|VariantedValue|StyleToken|BlobRef|HostLessPackageInfo|ProjectDepLocalResource|SiteFolder|Site|ArenaFrameGrid|ArenaFrameRow|ArenaFrameCell|ComponentArena|PageArena|Arena|FocusedFrameArena|ArenaChild|ArenaFrame|OpaqueType|StyleNode|RuleSet|Rule|VariantedRuleSet|Mixin|Theme|ThemeStyle|LocalPresets|ProjectDependency|ImageAsset|TplNode|TplTag|TplComponent|TplSlot|TplGroup|ColumnsSetting|Preset|PresetGroup|PageMeta|ComponentDataQuery|CodeComponentMeta|Component|Query|RestQuery|FetcherQuery|GraphqlQuery|NameArg|PlumeInfo|Variant|VariantGroup|ComponentVariantGroup|VariantSetting|EventHandler|Interaction|ColumnsConfig|Marker|StyleMarker|NodeMarker|RichText|RawText|ExprText|ExprBinding|Var|Cell|BindingStruct|Rep|Let|Param|Arg|Expr|RenderExpr|VirtualRenderExpr|CustomCode|DataSourceOpExpr|DataSourceTemplate|VarRef|ImageAssetRef|PageHref|VariantsRef|SimplePath|ObjectPath|State|Split|SplitSlice|RandomSplitSlice|SegmentSplitSlice|SplitContent|GlobalVariantSplitContent|ComponentVariantSplitContent|ComponentSwapSplitContent)\b
  message: Semgrep found a match
  languages: [ts]
  severity: ERROR
  fix: isClean($Y)($X)
- id: ensure
  patterns:
    - pattern: ensureInstance($X, $Y)
    - metavariable-regex:
        metavariable: $Y
        regex: \b(Num|Text|DateTime|Id|Bool|Img|Binary|Any|Collection|MapType|Optional|Union|Choice|ComponentInstance|PlumeInstance|QueryData|VariantedValue|StyleToken|BlobRef|HostLessPackageInfo|ProjectDepLocalResource|SiteFolder|Site|ArenaFrameGrid|ArenaFrameRow|ArenaFrameCell|ComponentArena|PageArena|Arena|FocusedFrameArena|ArenaChild|ArenaFrame|OpaqueType|StyleNode|RuleSet|Rule|VariantedRuleSet|Mixin|Theme|ThemeStyle|LocalPresets|ProjectDependency|ImageAsset|TplTag|TplComponent|TplSlot|TplGroup|ColumnsSetting|Preset|PresetGroup|PageMeta|ComponentDataQuery|CodeComponentMeta|Component|Query|RestQuery|FetcherQuery|GraphqlQuery|NameArg|PlumeInfo|Variant|VariantGroup|ComponentVariantGroup|VariantSetting|EventHandler|Interaction|ColumnsConfig|Marker|StyleMarker|NodeMarker|RawText|ExprText|ExprBinding|Var|Cell|Rep|Let|Param|Arg|RenderExpr|VirtualRenderExpr|CustomCode|DataSourceOpExpr|DataSourceTemplate|VarRef|ImageAssetRef|PageHref|VariantsRef|SimplePath|ObjectPath|State|Split|SplitSlice|RandomSplitSlice|SegmentSplitSlice|SplitContent|GlobalVariantSplitContent|ComponentVariantSplitContent|ComponentSwapSplitContent|Type|Scalar|Num|Text|DateTime|Id|Bool|Img|Binary|Any|Collection|MapType|Optional|Union|Choice|ComponentInstance|PlumeInstance|UserType|QueryData|VariantedValue|StyleToken|BlobRef|HostLessPackageInfo|ProjectDepLocalResource|SiteFolder|Site|ArenaFrameGrid|ArenaFrameRow|ArenaFrameCell|ComponentArena|PageArena|Arena|FocusedFrameArena|ArenaChild|ArenaFrame|OpaqueType|StyleNode|RuleSet|Rule|VariantedRuleSet|Mixin|Theme|ThemeStyle|LocalPresets|ProjectDependency|ImageAsset|TplNode|TplTag|TplComponent|TplSlot|TplGroup|ColumnsSetting|Preset|PresetGroup|PageMeta|ComponentDataQuery|CodeComponentMeta|Component|Query|RestQuery|FetcherQuery|GraphqlQuery|NameArg|PlumeInfo|Variant|VariantGroup|ComponentVariantGroup|VariantSetting|EventHandler|Interaction|ColumnsConfig|Marker|StyleMarker|NodeMarker|RichText|RawText|ExprText|ExprBinding|Var|Cell|BindingStruct|Rep|Let|Param|Arg|Expr|RenderExpr|VirtualRenderExpr|CustomCode|DataSourceOpExpr|DataSourceTemplate|VarRef|ImageAssetRef|PageHref|VariantsRef|SimplePath|ObjectPath|State|Split|SplitSlice|RandomSplitSlice|SegmentSplitSlice|SplitContent|GlobalVariantSplitContent|ComponentVariantSplitContent|ComponentSwapSplitContent)\b
  message: Semgrep found a match
  languages: [ts]
  severity: ERROR
  fix: ensureClean($Y)($X)
EOF

  find src/wab -name '*.ts' -o -name '*.tsx' | fgrep -v /plasmic/ | safe-xargs docker run --rm -v "${PWD}:/src" returntocorp/semgrep semgrep --config rule.yaml -a
}

use-astx() {
  cat > aa.js << "EOF"
exports.find = `$x instanceof $y`;
exports.where = {
  $y: astx => /\b(Num|Text|DateTime|Id|Bool|Img|Binary|Any|Collection|MapType|Optional|Union|Choice|ComponentInstance|PlumeInstance|QueryData|VariantedValue|StyleToken|BlobRef|HostLessPackageInfo|ProjectDepLocalResource|SiteFolder|Site|ArenaFrameGrid|ArenaFrameRow|ArenaFrameCell|ComponentArena|PageArena|Arena|FocusedFrameArena|ArenaChild|ArenaFrame|OpaqueType|StyleNode|RuleSet|Rule|VariantedRuleSet|Mixin|Theme|ThemeStyle|LocalPresets|ProjectDependency|ImageAsset|TplTag|TplComponent|TplSlot|TplGroup|ColumnsSetting|Preset|PresetGroup|PageMeta|ComponentDataQuery|CodeComponentMeta|Component|Query|RestQuery|FetcherQuery|GraphqlQuery|NameArg|PlumeInfo|Variant|VariantGroup|ComponentVariantGroup|VariantSetting|EventHandler|Interaction|ColumnsConfig|Marker|StyleMarker|NodeMarker|RawText|ExprText|ExprBinding|Var|Cell|Rep|Let|Param|Arg|RenderExpr|VirtualRenderExpr|CustomCode|DataSourceOpExpr|DataSourceTemplate|VarRef|ImageAssetRef|PageHref|VariantsRef|SimplePath|ObjectPath|State|Split|SplitSlice|RandomSplitSlice|SegmentSplitSlice|SplitContent|GlobalVariantSplitContent|ComponentVariantSplitContent|ComponentSwapSplitContent|Type|Scalar|Num|Text|DateTime|Id|Bool|Img|Binary|Any|Collection|MapType|Optional|Union|Choice|ComponentInstance|PlumeInstance|UserType|QueryData|VariantedValue|StyleToken|BlobRef|HostLessPackageInfo|ProjectDepLocalResource|SiteFolder|Site|ArenaFrameGrid|ArenaFrameRow|ArenaFrameCell|ComponentArena|PageArena|Arena|FocusedFrameArena|ArenaChild|ArenaFrame|OpaqueType|StyleNode|RuleSet|Rule|VariantedRuleSet|Mixin|Theme|ThemeStyle|LocalPresets|ProjectDependency|ImageAsset|TplNode|TplTag|TplComponent|TplSlot|TplGroup|ColumnsSetting|Preset|PresetGroup|PageMeta|ComponentDataQuery|CodeComponentMeta|Component|Query|RestQuery|FetcherQuery|GraphqlQuery|NameArg|PlumeInfo|Variant|VariantGroup|ComponentVariantGroup|VariantSetting|EventHandler|Interaction|ColumnsConfig|Marker|StyleMarker|NodeMarker|RichText|RawText|ExprText|ExprBinding|Var|Cell|BindingStruct|Rep|Let|Param|Arg|Expr|RenderExpr|VirtualRenderExpr|CustomCode|DataSourceOpExpr|DataSourceTemplate|VarRef|ImageAssetRef|PageHref|VariantsRef|SimplePath|ObjectPath|State|Split|SplitSlice|RandomSplitSlice|SegmentSplitSlice|SplitContent|GlobalVariantSplitContent|ComponentVariantSplitContent|ComponentSwapSplitContent)\b/.test(astx.stringValue)
}
exports.replace = `isClean$y($x)`;
  EOF

  cat > bb.js << "EOF"
exports.find = `ensureInstance($x, $y)`;
exports.where = {
  $y: astx => /\b(Num|Text|DateTime|Id|Bool|Img|Binary|Any|Collection|MapType|Optional|Union|Choice|ComponentInstance|PlumeInstance|QueryData|VariantedValue|StyleToken|BlobRef|HostLessPackageInfo|ProjectDepLocalResource|SiteFolder|Site|ArenaFrameGrid|ArenaFrameRow|ArenaFrameCell|ComponentArena|PageArena|Arena|FocusedFrameArena|ArenaChild|ArenaFrame|OpaqueType|StyleNode|RuleSet|Rule|VariantedRuleSet|Mixin|Theme|ThemeStyle|LocalPresets|ProjectDependency|ImageAsset|TplTag|TplComponent|TplSlot|TplGroup|ColumnsSetting|Preset|PresetGroup|PageMeta|ComponentDataQuery|CodeComponentMeta|Component|Query|RestQuery|FetcherQuery|GraphqlQuery|NameArg|PlumeInfo|Variant|VariantGroup|ComponentVariantGroup|VariantSetting|EventHandler|Interaction|ColumnsConfig|Marker|StyleMarker|NodeMarker|RawText|ExprText|ExprBinding|Var|Cell|Rep|Let|Param|Arg|RenderExpr|VirtualRenderExpr|CustomCode|DataSourceOpExpr|DataSourceTemplate|VarRef|ImageAssetRef|PageHref|VariantsRef|SimplePath|ObjectPath|State|Split|SplitSlice|RandomSplitSlice|SegmentSplitSlice|SplitContent|GlobalVariantSplitContent|ComponentVariantSplitContent|ComponentSwapSplitContent|Type|Scalar|Num|Text|DateTime|Id|Bool|Img|Binary|Any|Collection|MapType|Optional|Union|Choice|ComponentInstance|PlumeInstance|UserType|QueryData|VariantedValue|StyleToken|BlobRef|HostLessPackageInfo|ProjectDepLocalResource|SiteFolder|Site|ArenaFrameGrid|ArenaFrameRow|ArenaFrameCell|ComponentArena|PageArena|Arena|FocusedFrameArena|ArenaChild|ArenaFrame|OpaqueType|StyleNode|RuleSet|Rule|VariantedRuleSet|Mixin|Theme|ThemeStyle|LocalPresets|ProjectDependency|ImageAsset|TplNode|TplTag|TplComponent|TplSlot|TplGroup|ColumnsSetting|Preset|PresetGroup|PageMeta|ComponentDataQuery|CodeComponentMeta|Component|Query|RestQuery|FetcherQuery|GraphqlQuery|NameArg|PlumeInfo|Variant|VariantGroup|ComponentVariantGroup|VariantSetting|EventHandler|Interaction|ColumnsConfig|Marker|StyleMarker|NodeMarker|RichText|RawText|ExprText|ExprBinding|Var|Cell|BindingStruct|Rep|Let|Param|Arg|Expr|RenderExpr|VirtualRenderExpr|CustomCode|DataSourceOpExpr|DataSourceTemplate|VarRef|ImageAssetRef|PageHref|VariantsRef|SimplePath|ObjectPath|State|Split|SplitSlice|RandomSplitSlice|SegmentSplitSlice|SplitContent|GlobalVariantSplitContent|ComponentVariantSplitContent|ComponentSwapSplitContent)\b/.test(astx.stringValue)
}
exports.replace = `ensureClean$y($x)`;
  EOF

  yarn astx -f aa.js
  yarn astx -f bb.js
}

# git checkout .
# make

# perform structural replace here, either
# - manually use intellij (this was final solution)
# - use-comby
# - use-semgrep
# - use-astx

yarn run-ts tools/retype-throwaway/add-missing-imports.tsx

rm -f full.log
yarn tsc --noEmit &> full.log || true
wc -l full.log
cat full.log | wc -l
