/* eslint-disable dot-notation */
import './index';
import fetchMock, { MockRequest, MockResponse } from 'fetch-mock';
import { assert } from 'chai';
import type { CanvasKit, CanvasKitInit as CKInit } from '../../wasm_libs/types/canvaskit';
import {
  childShaderArraysDiffer,
  childShadersAreDifferent,
  defaultChildShaderScrapHashOrName, defaultImageURL, defaultScrapBody, numPredefinedUniforms, ShaderNode,
} from './index';
import { ChildShader, ScrapBody, ScrapID } from '../json';

// It is assumed that canvaskit.js has been loaded and this symbol is available globally.
declare const CanvasKitInit: typeof CKInit;

let canvasKit: CanvasKit | null = null;

const getCanvasKit = async (): Promise<CanvasKit> => {
  if (canvasKit) {
    return canvasKit;
  }
  canvasKit = await CanvasKitInit({ locateFile: (file: string) => `/canvaskit_assets/${file}` });
  if (!canvasKit) {
    throw new Error('Could not load CanvasKit');
  }
  return canvasKit;
};

const createShaderNode = async (): Promise<ShaderNode> => {
  const ck = await getCanvasKit();
  const node = new ShaderNode(ck);
  await node.setScrap(defaultScrapBody);
  return node;
};

const createShaderNodeWithChildShader = async (): Promise<ShaderNode> => {
  const ck = await getCanvasKit();
  const node = new ShaderNode(ck);

  const childScrapBody: ScrapBody = {
    Body: `half4 main(vec2 fragcoord) {
      return half4(0, 1, 0, 1);
    }`,
    Type: 'sksl',
    SKSLMetaData: {
      Children: [],
      ImageURL: '',
      Uniforms: [],
    },
  };
  fetchMock.get(`/_/load/${defaultChildShaderScrapHashOrName}`, childScrapBody);

  const scrapBodyWithChild: ScrapBody = {
    Body: `half4 main(vec2 fragcoord) {
      return half4(0, 1, 0, 1);
    }`,
    Type: 'sksl',
    SKSLMetaData: {
      Children: [{
        UniformName: 'childShader',
        ScrapHashOrName: defaultChildShaderScrapHashOrName,
      },
      ],
      ImageURL: '',
      Uniforms: [],
    },
  };
  await node.setScrap(scrapBodyWithChild);
  await fetchMock.flush();
  fetchMock.restore();

  return node;
};

describe('ShaderNode', async () => {
  it('constructor builds with a default shader', async () => {
    const node = await createShaderNode();
    node.compile();

    // Confirm that all the post-compile pre-calculations are done correctly.
    assert.equal(node.getUniformCount(), numPredefinedUniforms, 'The default shader doesn\'t have any user uniforms.');
    assert.equal(node.getUniform(0).name, 'iResolution', 'Confirm the predefined shaders show up in the uniforms.');
    assert.equal(node.getUniformFloatCount(), node.numPredefinedUniformValues, 'These are equal because the default shader has 0 user uniforms.');
    assert.isNotNull(node['uniformsMallocObj'], "We Malloc'd");
    assert.equal(node.numPredefinedUniformValues, 11, 'The number of predefined uniform values is calculated after compile() is called. This value will change if predefinedUniforms is changed.');
    assert.deepEqual(node.compileErrorLineNumbers, []);
    assert.equal(node.compileErrorMessage, '');
  });

  it('updates all values when a new shader is compiled.', async () => {
    const node = await createShaderNode();
    node.compile();
    assert.isNotNull(node.getShader([]));

    // Check our starting values.
    assert.equal(node.getUniformCount(), numPredefinedUniforms, 'The default shader doesn\'t have any user uniforms.');
    assert.equal(node.getUniform(0).name, 'iResolution', 'Confirm the predefined shaders show up in the uniforms.');
    assert.equal(node.getUniformFloatCount(), node.numPredefinedUniformValues, 'These are equal because the default shader has 0 user uniforms.');

    // Set code that has a user uniform, in this case with 4 floats.
    await node.setScrap({
      Type: 'sksl',
      Body: `uniform float4 iColorWithAlpha;

      half4 main(float2 fragCoord) {
        return half4(iColorWithAlpha);
      }
      `,
      SKSLMetaData: {
        Children: [],
        ImageURL: '',
        Uniforms: [1, 0, 1, 0],
      },
    });
    node.compile();
    assert.isNotNull(node.getShader([0, 0, 0, 0]));

    // Confirm that all the post-compile pre-calculations are done correctly for the new shader.
    assert.equal(node.getUniformCount(), numPredefinedUniforms + 1, 'The new shader has 1 user uniform.');
    assert.equal(node.getUniform(0).name, 'iResolution', 'Confirm the predefined shaders show up in the uniforms.');
    assert.equal(node.getUniformFloatCount(), node.numPredefinedUniformValues + 4, 'The user uniform contributes 4 floats to the total.');
  });

  it('correctly indicates when run() needs to be called.', async () => {
    const node = await createShaderNode();
    node.compile();

    assert.isFalse(node.needsCompile(), 'Should not need a run immediately after a call to compile().');

    const originalCode = node.shaderCode;
    node.shaderCode += '\n';
    assert.isTrue(node.needsCompile(), 'Needs compile when code has changed.');
    node.shaderCode = originalCode;
    assert.isFalse(node.needsCompile(), 'No longer needs a compile when change is undone.');
  });

  it('correctly indicates when save() needs to be called.', async () => {
    const node = await createShaderNode();
    node.compile();

    const startingUniformValues = [1, 0, 1, 0];
    const modifiedUniformValues = [1, 1, 1, 1];

    // Set code that has a user uniform, in this case with 4 floats, because
    // saving is not only indicated when the code changes, but when the user
    // uniforms change.
    await node.setScrap({
      Type: 'sksl',
      Body: `uniform float4 iColorWithAlpha;

      half4 main(float2 fragCoord) {
        return half4(iColorWithAlpha);
      }
      `,
      SKSLMetaData: {
        Children: [],
        ImageURL: '',
        Uniforms: startingUniformValues,
      },
    });
    node.compile();

    const originalCode = node.shaderCode;
    assert.isFalse(node.needsSave(), 'No need to save at the start.');
    // Changing the code means we need to save.

    node.shaderCode += '\n';
    assert.isTrue(node.needsSave(), 'Needs save if code changed.');
    node.shaderCode = originalCode;
    assert.isFalse(node.needsSave(), "Doesn't need save when code restored.");

    // Also changing the user uniform values means we need to save.
    node.currentUserUniformValues = modifiedUniformValues;
    assert.isTrue(node.needsSave(), 'Needs save if uniform values changed.');
    node.currentUserUniformValues = startingUniformValues;
    assert.isFalse(node.needsSave(), "Doesn't need save if uniform values restored.");
  });

  it('reports compiler errors', async () => {
    const node = await createShaderNode();
    node.compile();
    await node.setScrap({
      Type: 'sksl',
      Body: `uniform float4 iColorWithAlpha;

      half4 main(float2 fragCoord) {
        return half4(iColorWithAlpha) // Missing trailing semicolon.
      }
      `,
      SKSLMetaData: {
        Children: [],
        ImageURL: '',
        Uniforms: [1, 0, 1, 0],
      },
    });
    node.compile();

    assert.deepEqual(node.compileErrorLineNumbers, [5]);
    node.compileErrorMessage.startsWith("error: 5: expected ';', but found '}'");
  });

  it('makes a copy of the ScrapBody', async () => {
    const node = await createShaderNode();
    const startScrap = node.getScrap();
    assert.isNotEmpty(startScrap.Body);
    startScrap.Body = '';
    // Confirm we haven't changed the original scrap.
    assert.isNotEmpty(node['body']!.Body);
  });

  it('always starts with non-null input image', async () => {
    const node = await createShaderNode();
    assert.isNotNull(node.inputImageElement);
  });

  it('protects against unsafe URLs', async () => {
    const node = await createShaderNode();
    node['currentImageURL'] = 'data:foo';
    assert.equal(node.getCurrentImageURL(), 'data:foo');
    assert.equal(node.getSafeImageURL(), defaultImageURL);
  });

  it('reverts to empty image URL if image fails to load.', async () => {
    const node = await createShaderNode();
    await node.setCurrentImageURL('/dist/some-unknown-image.png');
    assert.equal(node.getCurrentImageURL(), '');
  });

  describe('child shader', () => {
    it('is created on loadScrap', async () => {
      const node = await createShaderNodeWithChildShader();
      assert.equal(1, node.children.length);
      assert.equal(defaultChildShaderScrapHashOrName, node.children[0]['scrapID']);
      assert.equal(node.getChildShader(0).UniformName, 'childShader');
    });

    it('can be removed', async () => {
      const node = await createShaderNodeWithChildShader();
      node.removeChildShader(0);
      assert.equal(0, node.children.length);
    });

    it('throws on out of bounds when removing shader', async () => {
      const node = await createShaderNodeWithChildShader();
      assert.throws(() => {
        node.removeChildShader(2);
      });
    });

    it('throws on out of bounds when accessing child shader', async () => {
      const node = await createShaderNodeWithChildShader();
      assert.throws(() => {
        node.getChildShader(2);
      });
    });

    it('can be appended', async () => {
      const node = await createShaderNode();

      const childScrapBody: ScrapBody = {
        Body: `half4 main(vec2 fragcoord) {
          return half4(0, 1, 0, 1);
        }`,
        Type: 'sksl',
        SKSLMetaData: {
          Children: [],
          ImageURL: '',
          Uniforms: [],
        },
      };
      fetchMock.get(`/_/load/${defaultChildShaderScrapHashOrName}`, childScrapBody);

      await node.appendNewChildShader();
      assert.equal(1, node.children.length);
      assert.equal(defaultChildShaderScrapHashOrName, node.children[0]['scrapID']);
      await fetchMock.flush();
      assert.isTrue(fetchMock.done());
      fetchMock.restore();
    });

    it('has a name', async () => {
      const node = await createShaderNodeWithChildShader();
      assert.equal(node.getChildShaderUniformName(0), 'childShader');
    });

    it('has uniform declarations', async () => {
      const node = await createShaderNodeWithChildShader();
      assert.equal(node.getChildShaderUniforms(), 'uniform shader childShader;');
    });

    it('has a name that can be changed', async () => {
      const node = await createShaderNodeWithChildShader();
      const newUniformName = 'someNewName';

      const childScrapBody: ScrapBody = {
        Body: `half4 main(vec2 fragcoord) {
          return half4(0, 1, 0, 1);
        }`,
        Type: 'sksl',
        SKSLMetaData: {
          Children: [],
          ImageURL: '',
          Uniforms: [],
        },
      };
      fetchMock.get(`/_/load/${defaultChildShaderScrapHashOrName}`, childScrapBody);

      await node.setChildShaderUniformName(0, newUniformName);
      assert.equal(node.getChildShaderUniformName(0), newUniformName);

      await fetchMock.flush();
      assert.isTrue(fetchMock.done());
      fetchMock.restore();
    });

    it('raises on invalid child shader names', async () => {
      const node = await createShaderNodeWithChildShader();
      await node.setChildShaderUniformName(0, 'this is an invalid uniform name because it contains spaces')
        .then(() => assert.fail())
        .catch((err: Error) => assert.match(err.message, /Invalid uniform name/));
    });

    it('raises on out of bounds', async () => {
      const node = await createShaderNodeWithChildShader();
      await node.setChildShaderUniformName(1, 'aNewName')
        .then(() => assert.fail())
        .catch((err: Error) => assert.match(err.message, /does not exist/));
    });

    it('saves depth first', async () => {
      const parentNodeSavedID = 'parentNodeSavedID';
      const childNodeSavedID = 'childNodeSavedID';
      const node = await createShaderNodeWithChildShader();

      // The save endpoint should be called twice, the first time from the child
      // node, and the second time from the parent node.
      const callOrder = [childNodeSavedID, parentNodeSavedID];
      const bodiesSent = [
        '{"Body":"half4 main(vec2 fragcoord) {\\n      return half4(0, 1, 0, 1);\\n    }","Type":"sksl","SKSLMetaData":{"Uniforms":[],"ImageURL":"","Children":[]}}',
        '{"Body":"half4 main(vec2 fragcoord) {\\n      return half4(0, 1, 0, 1);\\n    }","Type":"sksl","SKSLMetaData":{"Uniforms":[],"ImageURL":"","Children":[{"UniformName":"childShader","ScrapHashOrName":"childNodeSavedID"}]}}',
      ];
      let call = 0;
      fetchMock.post('/_/save/', (url: string, opts: MockRequest): MockResponse => {
        const { body } = opts;
        assert.equal(body, bodiesSent[call]);
        const resp: ScrapID = {
          Hash: callOrder[call],
        };
        call++;
        return resp;
      }, {
        sendAsJson: true,
      });

      const newID = await node.saveScrap();

      await fetchMock.flush();
      assert.isTrue(fetchMock.done());
      fetchMock.restore();

      assert.equal(newID, parentNodeSavedID);
    });
  });

  describe('childShadersAreDifferent', () => {
    it('detects differences', () => {
      const a: ChildShader = {
        UniformName: 'foo',
        ScrapHashOrName: '@someName',
      };
      const b: ChildShader = {
        UniformName: 'bar',
        ScrapHashOrName: '@someName',
      };
      const c: ChildShader = {
        UniformName: 'foo',
        ScrapHashOrName: '@someDifferentName',
      };

      assert.isTrue(childShadersAreDifferent(a, b));
      assert.isTrue(childShadersAreDifferent(b, c));
      assert.isTrue(childShadersAreDifferent(a, c));
      assert.isFalse(childShadersAreDifferent(a, a));
    });
  });

  describe('childShaderArraysDiffer', () => {
    it('handles empty arrays', () => {
      assert.isFalse(childShaderArraysDiffer([], []));
    });

    it('handles different sized arrays', () => {
      const a: ChildShader = {
        UniformName: 'foo',
        ScrapHashOrName: '@someName',
      };

      assert.isTrue(childShaderArraysDiffer([], [a]));
      assert.isTrue(childShaderArraysDiffer([a], []));
      assert.isTrue(childShaderArraysDiffer([a], [a, a]));
      assert.isFalse(childShaderArraysDiffer([a], [a]));
    });
  });
});
