/* eslint-disable dot-notation */
import './index';
import { assert } from 'chai';
import { numPredefinedUniforms, ShaderNode } from './index';
import { CanvasKit } from '../../build/canvaskit/canvaskit';

// eslint-disable-next-line @typescript-eslint/no-var-requires
const CanvasKitInit = require('../../build/canvaskit/canvaskit.js');

let canvasKit: CanvasKit | null = null;

const getCanvasKit = async (): Promise<CanvasKit> => {
  if (canvasKit) {
    return canvasKit;
  }
  canvasKit = await CanvasKitInit({ locateFile: (file: string) => `https://particles.skia.org/dist/${file}` });
  return canvasKit!;
};

const createShaderNode = async (): Promise<ShaderNode> => {
  const ck = await getCanvasKit();
  const image = ck.MakeImageFromCanvasImageSource(new Image(512, 512));
  const shader1 = image.makeShaderOptions(ck.TileMode.Clamp, ck.TileMode.Clamp, ck.FilterMode.Linear, ck.MipmapMode.None);
  const shader2 = image.makeShaderOptions(ck.TileMode.Clamp, ck.TileMode.Clamp, ck.FilterMode.Linear, ck.MipmapMode.None);

  return new ShaderNode(ck, [shader1, shader2]);
};

describe('ShaderNode', async () => {
  it('constructor throws when not passed in the correct number of image shaders', async () => {
    const ck = await getCanvasKit();
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    assert.throws(() => { const node = new ShaderNode(ck, []); });
  });

  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.
    node.setScrap({
      Type: 'sksl',
      Body: `uniform float4 iColorWithAlpha;

      half4 main(float2 fragCoord) {
        return half4(iColorWithAlpha);
      }
      `,
      SKSLMetaData: {
        Children: [],
        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.
    node.setScrap({
      Type: 'sksl',
      Body: `uniform float4 iColorWithAlpha;

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

    // Changing the code means we need to save.
    const originalCode = node.shaderCode;
    assert.isFalse(node.needsSave());
    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();
    node.setScrap({
      Type: 'sksl',
      Body: `uniform float4 iColorWithAlpha;

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

    assert.deepEqual(node.compileErrorLineNumbers, [4]);
    node.compileErrorMessage.startsWith('error: 4:');
  });
});
