import re

import gradio as gr
import torch
from transformers import T5ForConditionalGeneration, RobertaTokenizer


tokenizer = RobertaTokenizer.from_pretrained("mamiksik/CommitPredictorT5PL", revision="fb08d01")
model = T5ForConditionalGeneration.from_pretrained("mamiksik/CommitPredictorT5PL", revision="fb08d01")


def parse_files(patch):
    accumulator = []
    lines = patch.splitlines()

    filename_before = None
    for line in lines:
        if line.startswith("index") or line.startswith("diff"):
            continue
        if line.startswith("---"):
            filename_before = line.split(" ", 1)[1][1:]
            continue

        if line.startswith("+++"):
            filename_after = line.split(" ", 1)[1][1:]

            if filename_before == filename_after:
                accumulator.append(f"<ide><path>{filename_before}")
            else:
                accumulator.append(f"<add><path>{filename_after}")
                accumulator.append(f"<del><path>{filename_before}")
            continue

        line = re.sub("@@[^@@]*@@", "", line)
        if len(line) == 0:
            continue

        if line[0] == "+":
            line = line.replace("+", "<add>", 1)
        elif line[0] == "-":
            line = line.replace("-", "<del>", 1)
        else:
            line = f"<ide>{line}"

        accumulator.append(line)

    return '\n'.join(accumulator)


def predict(patch, max_length, min_length, num_beams, prediction_count):
    input_text = parse_files(patch)
    with torch.no_grad():
        token_count = tokenizer(input_text, return_tensors="pt").input_ids.shape[1]

        input_ids = tokenizer(
            input_text,
            truncation=True,
            padding=True,
            return_tensors="pt",
        ).input_ids

        outputs = model.generate(
            input_ids,
            max_length=max_length,
            min_length=min_length,
            num_beams=num_beams,
            num_return_sequences=prediction_count,
        )

    result = tokenizer.batch_decode(outputs, skip_special_tokens=True)
    return token_count, input_text, {k: 0 for k in result}


iface = gr.Interface(fn=predict, inputs=[
    gr.Textbox(label="Patch (as generated by git diff)"),
    gr.Slider(1, 128, value=40, label="Max message length"),
    gr.Slider(1, 128, value=5, label="Min message length"),
    gr.Slider(1, 10, value=7, label="Number of beams"),
    gr.Slider(1, 15, value=5, label="Number of predictions"),
], outputs=[
    gr.Textbox(label="Token count"),
    gr.Textbox(label="Parsed patch"),
    gr.Label(label="Predictions")
], examples=[
["""
diff --git a/.github/workflows/pylint.yml b/.github/workflows/codestyle_checks.yml
similarity index 86%
rename from .github/workflows/pylint.yml
rename to .github/workflows/codestyle_checks.yml
index a5d5c4d9..8cbf9713 100644
--- a/.github/workflows/pylint.yml
+++ b/.github/workflows/codestyle_checks.yml
@@ -20,3 +20,6 @@ jobs:
     - name: Analysing the code with pylint
       run: |
         pylint --rcfile=.pylintrc webapp core
+    - name: Analysing the code with flake8
+      run: |
+        flake8
""", 40, 5, 7, 5],
["""
diff --git a/packages/react-native-renderer/src/ReactFabricHostConfig.js b/packages/react-native-renderer/src/ReactFabricHostConfig.js
index 078bf1f11ac6..b6d370882ae4 100644
--- a/packages/react-native-renderer/src/ReactFabricHostConfig.js
+++ b/packages/react-native-renderer/src/ReactFabricHostConfig.js
@@ -18,7 +18,10 @@ import type {
   TouchedViewDataAtPoint,
 } from './ReactNativeTypes';
 
-import {mountSafeCallback_NOT_REALLY_SAFE} from './NativeMethodsMixinUtils';
+import {
+  mountSafeCallback_NOT_REALLY_SAFE,
+  warnForStyleProps,
+} from './NativeMethodsMixinUtils';
 import {create, diff} from './ReactNativeAttributePayload';
 
 import {dispatchEvent} from './ReactFabricEventEmitter';
@@ -52,6 +55,7 @@ const {
   unstable_DefaultEventPriority: FabricDefaultPriority,
   unstable_DiscreteEventPriority: FabricDiscretePriority,
   unstable_getCurrentEventPriority: fabricGetCurrentEventPriority,
+  setNativeProps,
 } = nativeFabricUIManager;
 
 const {get: getViewConfigForType} = ReactNativeViewConfigRegistry;
@@ -208,12 +212,14 @@ class ReactFabricHostComponent {
 
   setNativeProps(nativeProps: Object) {
     if (__DEV__) {
-      console.error(
-        'Warning: setNativeProps is not currently supported in Fabric',
-      );
+      warnForStyleProps(nativeProps, this.viewConfig.validAttributes);
     }
+    const updatePayload = create(nativeProps, this.viewConfig.validAttributes);
 
-    return;
+    const {stateNode} = this._internalInstanceHandle;
+    if (stateNode != null && updatePayload != null) {
+      setNativeProps(stateNode.node, updatePayload);
+    }
   }
 
   // This API (addEventListener, removeEventListener) attempts to adhere to the
diff --git a/packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/InitializeNativeFabricUIManager.js b/packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/InitializeNativeFabricUIManager.js
index abb2883d387e..ab4fc291d6d6 100644
--- a/packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/InitializeNativeFabricUIManager.js
+++ b/packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/InitializeNativeFabricUIManager.js
@@ -117,6 +117,8 @@ const RCTFabricUIManager = {
 
   dispatchCommand: jest.fn(),
 
+  setNativeProps: jest.fn(),
+
   sendAccessibilityEvent: jest.fn(),
 
   registerEventHandler: jest.fn(function registerEventHandler(callback) {}),
diff --git a/packages/react-native-renderer/src/__tests__/ReactFabricHostComponent-test.internal.js b/packages/react-native-renderer/src/__tests__/ReactFabricHostComponent-test.internal.js
index 337a4976bbe8..51e056d1c8bc 100644
--- a/packages/react-native-renderer/src/__tests__/ReactFabricHostComponent-test.internal.js
+++ b/packages/react-native-renderer/src/__tests__/ReactFabricHostComponent-test.internal.js
@@ -38,7 +38,7 @@ function mockRenderKeys(keyLists) {
 
   const mockContainerTag = 11;
   const MockView = createReactNativeComponentClass('RCTMockView', () => ({
-    validAttributes: {},
+    validAttributes: {foo: true},
     uiViewClassName: 'RCTMockView',
   }));
 
@@ -200,21 +200,15 @@ describe('measureLayout', () => {
 });
 
 describe('setNativeProps', () => {
-  test('setNativeProps(...) emits a warning', () => {
+  test('setNativeProps(...) invokes setNativeProps on Fabric UIManager', () => {
     const {
       UIManager,
     } = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface');
 
     const [[fooRef]] = mockRenderKeys([['foo']]);
+    fooRef.setNativeProps({foo: 'baz'});
 
-    expect(() => {
-      fooRef.setNativeProps({});
-    }).toErrorDev(
-      ['Warning: setNativeProps is not currently supported in Fabric'],
-      {
-        withoutStack: true,
-      },
-    );
     expect(UIManager.updateView).not.toBeCalled();
+    expect(nativeFabricUIManager.setNativeProps).toHaveBeenCalledTimes(1);
   });
 });
diff --git a/scripts/flow/react-native-host-hooks.js b/scripts/flow/react-native-host-hooks.js
index 584f24ee084c..e3c98114935f 100644
--- a/scripts/flow/react-native-host-hooks.js
+++ b/scripts/flow/react-native-host-hooks.js
@@ -186,7 +186,7 @@ declare var nativeFabricUIManager: {
       payload: Object,
     ) => void,
   ) => void,
-
+  setNativeProps: (node: Object, nativeProps: Object) => Object,
   dispatchCommand: (node: Object, command: string, args: Array<any>) => void,
   sendAccessibilityEvent: (node: Object, eventTypeName: string) => void,
""", 40, 5, 7, 5]
]
)

if __name__ == "__main__":
    iface.launch()