import * as path from 'path';
import { NoteGraphAPI } from '../../src/note-graph';
import { generateLinkReferences } from '../../src/janitor';
import { bootstrap } from '../../src/bootstrap';
import { createConfigFromFolders } from '../../src/config';
import { Services } from '../../src';
import { FileDataStore } from '../../src/services/datastore';

describe('generateLinkReferences', () => {
  let _graph: NoteGraphAPI;

  beforeAll(async () => {
    const config = createConfigFromFolders([
      path.join(__dirname, '../__scaffold__'),
    ]);
    const services: Services = {
      dataStore: new FileDataStore(config),
    };
    _graph = await bootstrap(config, services).then(foam => foam.notes);
  });

  it('initialised test graph correctly', () => {
    expect(_graph.getNotes().length).toEqual(6);
  });

  it('should add link references to a file that does not have them', () => {
    const note = _graph.getNotes({ slug: 'index' })[0];
    const expected = {
      newText: `
[//begin]: # "Autogenerated link references for markdown compatibility"
[first-document]: first-document "First Document"
[second-document]: second-document "Second Document"
[file-without-title]: file-without-title "file-without-title"
[//end]: # "Autogenerated link references"`,
      range: {
        start: {
          line: 10,
          column: 1,
          offset: 140,
        },
        end: {
          line: 10,
          column: 1,
          offset: 140,
        },
      },
    };

    const actual = generateLinkReferences(note, _graph, false);

    expect(actual!.range.start).toEqual(expected.range.start);
    expect(actual!.range.end).toEqual(expected.range.end);
    expect(actual!.newText).toEqual(expected.newText);
  });

  it('should remove link definitions from a file that has them, if no links are present', () => {
    const note = _graph.getNotes({ slug: 'second-document' })[0];

    const expected = {
      newText: '',
      range: {
        start: {
          line: 7,
          column: 1,
          offset: 105,
        },
        end: {
          line: 9,
          column: 43,
          offset: 269,
        },
      },
    };

    const actual = generateLinkReferences(note, _graph, false);

    expect(actual!.range.start).toEqual(expected.range.start);
    expect(actual!.range.end).toEqual(expected.range.end);
    expect(actual!.newText).toEqual(expected.newText);
  });

  it('should update link definitions if they are present but changed', () => {
    const note = _graph.getNotes({ slug: 'first-document' })[0];

    const expected = {
      newText: `[//begin]: # "Autogenerated link references for markdown compatibility"
[file-without-title]: file-without-title "file-without-title"
[//end]: # "Autogenerated link references"`,
      range: {
        start: {
          line: 9,
          column: 1,
          offset: 145,
        },
        end: {
          line: 11,
          column: 43,
          offset: 312,
        },
      },
    };

    const actual = generateLinkReferences(note, _graph, false);

    expect(actual!.range.start).toEqual(expected.range.start);
    expect(actual!.range.end).toEqual(expected.range.end);
    expect(actual!.newText).toEqual(expected.newText);
  });

  it('should not cause any changes if link reference definitions were up to date', () => {
    const note = _graph.getNotes({ slug: 'third-document' })[0];

    const expected = null;

    const actual = generateLinkReferences(note, _graph, false);

    expect(actual).toEqual(expected);
  });
});
