/**
 * @license
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/* global process */

import fs from 'fs';
import { URL } from 'url';
import Ajv from 'ajv';
import { assert } from 'chai';
import fetch from 'node-fetch';
import resolve from 'resolve';

// file or URL location
let url = '';
// find the URL parameter (which might be a relative path to a file)
let found_url = false;
process.argv.forEach((val, index) => {
  if (val.startsWith('--url')) {
    found_url = true;
    if (val[5] === '=') {
      url = val.split('=')[1];
    } else {
      // assume the next parameter is a URL
      url = process.argv[index + 1];
    }
  }
});

function requireJSON(name: string): Record<string, unknown> {
  const resolvedPath = resolve.sync(name);
  const data = fs.readFileSync(resolvedPath).toString();
  return JSON.parse(data) as Record<string, unknown>;
}

const DEFINITIONS = [
  'annotations',
  'bodyTarget',
  'choiceSet',
  'collections',
  'id',
  'otherProperties',
  'specificResource',
].map((name) => requireJSON(`web-annotation-tests/definitions/${name}.json`));

const MUSTS = requireJSON(
  'web-annotation-tests/annotations/annotationMusts.test',
);

const META_SCHEMA = requireJSON('ajv/lib/refs/json-schema-draft-04.json');

const ajv = new Ajv({ schemaId: 'auto', meta: false });
ajv.addMetaSchema(META_SCHEMA);
DEFINITIONS.forEach((schema) => ajv.addSchema(schema));

describe('Test JSON against Schemas', () => {
  let data: Record<string, unknown>;

  before(async function () {
    if (!found_url) {
      this.skip();
    } else {
      // load the data from the file or URL
      const url_parsed = new URL(url);
      if (url_parsed.pathname !== url_parsed.href) {
        const data_response = await fetch(url_parsed.href);
        data = (await data_response.json()) as Record<string, unknown>;
      } else {
        // assume we have a local file and use that
        data = JSON.parse(
          fs.readFileSync(url_parsed.pathname, 'utf8'),
        ) as Record<string, unknown>;
      }

      if (!data) {
        this.skip();
      }
    }
  });

  const assertions = MUSTS['assertions'] as [string];
  assertions.forEach((schemaPath: string) => {
    const schema = requireJSON(`web-annotation-tests/${schemaPath}`);
    it(schema['title'] as string, () => {
      const valid = ajv.validate(schema, data);
      assert.isOk(valid, ajv.errorsText());
    });
  });
});
