import { MAP, SCALAR, SEQ } from '../nodes/identity.mjs';
import { map } from './common/map.mjs';
import { seq } from './common/seq.mjs';
import { string } from './common/string.mjs';
import { getTags, coreKnownTags } from './tags.mjs';

const sortMapEntriesByKey = (a, b) => a.key < b.key ? -1 : a.key > b.key ? 1 : 0;
class Schema {
  constructor({
    compat,
    customTags,
    merge,
    resolveKnownTags,
    schema,
    sortMapEntries,
    toStringDefaults
  }) {
    this.compat = Array.isArray(compat) ? getTags(compat, 'compat') : compat ? getTags(null, compat) : null;
    this.name = typeof schema === 'string' && schema || 'core';
    this.knownTags = resolveKnownTags ? coreKnownTags : {};
    this.tags = getTags(customTags, this.name, merge);
    this.toStringOptions = toStringDefaults ?? null;
    Object.defineProperty(this, MAP, {
      value: map
    });
    Object.defineProperty(this, SCALAR, {
      value: string
    });
    Object.defineProperty(this, SEQ, {
      value: seq
    });
    // Used by createMap()
    this.sortMapEntries = typeof sortMapEntries === 'function' ? sortMapEntries : sortMapEntries === true ? sortMapEntriesByKey : null;
  }
  clone() {
    const copy = Object.create(Schema.prototype, Object.getOwnPropertyDescriptors(this));
    copy.tags = this.tags.slice();
    return copy;
  }
}

export { Schema };
