/**
 * @file create-logger.js
 * @module 생성-로거
 */
'글로벌/창'에서 창 가져오기;

// 로깅 기록에 대한 개인 추적 변수입니다.
let history = [];

/**
 * 메시지 유형에 따라 콘솔 및 기록에 메시지를 기록합니다.
 *
 * @사적인
 * @param {문자열} 유형
 * 사용할 콘솔 메소드의 이름.
 *
 * @param {배열} 인수
 * 일치하는 콘솔 메서드에 전달할 인수입니다.
 */
const LogByTypeFactory = (이름, 로그) => (유형, 수준, 인수) => {
  const lvl = log.levels[레벨];
  const lvlRegExp = new RegExp(`^(${lvl})$`);

  if (타입 !== '로그') {

    // "log"가 아닌 경우 메시지 앞에 유형을 추가합니다.
    args.unshift(type.toUpperCase() + ':');
  }

  // 기록에 추가한 후 콘솔 접두사를 추가합니다.
  args.unshift(이름 + ':');

  // 이 지점에서 인수의 복제본을 기록에 추가합니다.
  if (역사) {
    history.push([].concat(args));

    // 1000개의 히스토리 항목만 저장
    const splice = history.length - 1000;

    history.splice(0, 스플라이스 > 0 ? 스플라이스: 0);
  }

  // 콘솔이 없으면 메시지 출력을 시도하지 마십시오.
  // 여전히 히스토리에 저장됩니다.
  if (!window.console) {
    반품;
  }

  // 이 함수 외부에서 한 번 설정했지만 포함하고 있었습니다.
  // 함수에서 콘솔이 존재하지 않는 경우를 더 쉽게 테스트할 수 있습니다.
  // 모듈이 실행될 때.
  let fn = window.console[유형];

  만약 (!fn && 유형 === '디버그') {
    // 특정 브라우저는 console.debug를 지원하지 않습니다. 그런 분들을 위해 우리는
    // 가장 가까운 비교 가능한 로그로 기본 설정해야 합니다.
    fn = window.console.info || window.console.log;
  }

  // 콘솔이 없거나 이 유형이
  // 현재 로깅 수준.
  if (!fn || !lvl || !lvlRegExp.test(유형)) {
    반품;
  }

  fn[Array.isArray(args) ? '적용' : '호출'](window.console, args);
};

내보내기 기본 기능 createLogger(name) {
  // 이것은 로깅 수준에 대한 개인 추적 변수입니다.
  let level = '정보';

  // 특정 로그 및 기록에 바인딩된 커리 logByType
  let logByType;

  /**
   * 일반 디버그 메시지를 기록합니다. `console.log`와 유사합니다.
   *
   * [제한 사항](https://github.com/jsdoc3/jsdoc/issues/955#issuecomment-313829149)으로 인해
   * JSDoc 템플릿의 경우 이를 둘 다 함수로 제대로 문서화할 수 없습니다.
   * 및 네임스페이스이므로 함수 서명은 여기에 문서화되어 있습니다.
   *
   * #### 인수
   * ##### *인수
   * 혼합[]
   *
   * `console.log()`에 전달될 수 있는 모든 값의 조합.
   *
   * #### 반환 값
   *
   * `정의되지 않음`
   *
   * @네임스페이스
   * @param {혼합[]} 인수
   * 기록해야 하는 하나 이상의 메시지 또는 개체입니다.
   */
  const 로그 = 함수(...인수) {
    logByType('log', level, args);
  };

  // 아래의 로깅 메소드가 사용하는 logByType 헬퍼입니다.
  logByType = LogByTypeFactory(이름, 로그);

  /**
   * 이전 이름을 새 이름에 연결하는 새 하위 로거를 만듭니다.
   *
   * 예를 들어 `videojs.log.createLogger('player')`를 수행한 다음 해당 로거를 사용하면 다음이 기록됩니다.
   * ```js
   * mylogger('foo');
   * // > VIDEOJS: 플레이어: foo
   * ```
   *
   * @param {문자열} 이름
   * 추가할 이름은 새 로거를 호출합니다.
   * @return {객체}
   */
  log.createLogger = (하위 이름) => createLogger(이름 + ': ' + 하위 이름);

  /**
   * 키가 수준 이름인 사용 가능한 로깅 수준의 열거
   * 및 값은 허용되는 로깅 방법을 포함하는 `|`로 구분된 문자열입니다.
   * 해당 로깅 수준에서. 이 문자열은 정규식을 만드는 데 사용됩니다.
   * 호출되는 함수 이름과 일치합니다.
   *
   * Video.js에서 제공하는 레벨은 다음과 같습니다.
   *
   * - `끄기`: 일치하는 통화가 없습니다. 'false'로 캐스팅할 수 있는 모든 값은
   * 이 효과. 가장 제한적입니다.
   * - `모두`: Video.js 제공 함수(`debug`, `log`,
   * `log.warn` 및 `log.error`).
   * - `디버그`: `log.debug`, `log`, `log.warn` 및 `log.error` 호출과 일치합니다.
   * - `정보`(기본값): `log`, `log.warn` 및 `log.error` 호출과 일치합니다.
   * - `경고`: `log.warn` 및 `log.error` 호출과 일치합니다.
   * - `오류`: `log.error` 호출만 일치합니다.
   *
   * @type {객체}
   */
  로그.레벨 = {
    모두: '디버그|로그|경고|오류',
    끄다: '',
    디버그: '디버그|로그|경고|오류',
    정보: '로그|경고|오류',
    경고: '경고|오류',
    오류: '오류',
    기본값: 수준
  };

  /**
   * 현재 로깅 수준을 가져오거나 설정합니다.
   *
   * {@link module:log.levels}의 키와 일치하는 문자열이 제공되면 동작
   * 세터로.
   *
   * @param {문자열} [lvl]
   * 새로운 로깅 수준을 설정하려면 유효한 수준을 전달하십시오.
   *
   * @return {문자열}
   * 현재 로깅 수준.
   */
  로그레벨 = (lvl) => {
    if (typeof lvl === '문자열') {
      if (!log.levels.hasOwnProperty(lvl)) {
        throw new Error(`"${lvl}" in not a valid log level`);
      }
      레벨 = 레벨;
    }
    반환 수준;
  };

  /**
   * 히스토리에 기록된 모든 것을 포함하는 배열을 반환합니다.
   *
   * 이 배열은 내부 기록 레코드의 얕은 복제본입니다. 그러나 그
   * 콘텐츠는 복제되지 _않습니다_. 따라서 이 배열 내부의 개체를 변경하면
   * 역사에서 그들을 돌연변이.
   *
   * @return {배열}
   */
  로그 기록 = () => 역사 ? [].concat(히스토리) : [];

  /**
   * 주어진 로거 이름으로 기록을 필터링할 수 있습니다.
   *
   * @param {문자열} fname
   * 필터링할 이름
   *
   * @return {배열}
   * 반환할 필터링된 목록
   */
  log.history.filter = (fname) => {
    return (히스토리 || []).filter((historyItem) => {
      // 각 historyItem의 첫 번째 항목에 `fname`이 포함되어 있으면 일치 항목입니다.
      return new RegExp(`.*${fname}.*`).test(historyItem[0]);
    });
  };

  /**
   * 내부 기록 추적을 지우지만 추가 기록을 방지하지는 않습니다.
   * 추적.
   */
  log.history.clear = () => {
    if (역사) {
      히스토리.길이 = 0;
    }
  };

  /**
   * 현재 활성화된 경우 기록 추적을 비활성화합니다.
   */
  log.history.disable = () => {
    if (기록 !== null) {
      히스토리.길이 = 0;
      역사 = null;
    }
  };

  /**
   * 현재 비활성화된 경우 기록 추적을 활성화합니다.
   */
  log.history.enable = () => {
    if (기록 === null) {
      역사 = [];
    }
  };

  /**
   * 오류 메시지를 기록합니다. `console.error`와 유사합니다.
   *
   * @param {혼합[]} 인수
   * 오류로 기록되어야 하는 하나 이상의 메시지 또는 개체
   */
  log.error = (...인수) => logByType('오류', 수준, 인수);

  /**
   * 경고 메시지를 기록합니다. `console.warn`과 유사합니다.
   *
   * @param {혼합[]} 인수
   * 경고로 기록되어야 하는 하나 이상의 메시지 또는 개체.
   */
  log.warn = (...인수) => logByType('경고', 수준, 인수);

  /**
   * 디버그 메시지를 기록합니다. `console.debug`와 비슷하지만 비슷한 역할을 할 수도 있습니다.
   * `console.debug`를 사용할 수 없는 경우 로그
   *
   * @param {혼합[]} 인수
   * 디버그로 기록되어야 하는 하나 이상의 메시지 또는 개체.
   */
  log.debug = (...인수) => logByType('debug', level, args);

  리턴 로그;
}