// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library mime.mime_type;

import 'default_extension_map.dart';
import 'magic_number.dart';

final MimeTypeResolver _globalResolver = new MimeTypeResolver();

/**
 * The maximum number of bytes needed, to match all default magic-numbers.
 */
int get defaultMagicNumbersMaxLength => _globalResolver.magicNumbersMaxLength;

/**
 * Extract the extension from [path] and use that for MIME-type lookup, using
 * the default extension map.
 *
 * If no matching MIME-type was found, `null` is returned.
 *
 * If [headerBytes] is present, a match for known magic-numbers will be
 * performed first. This allows the correct mime-type to be found, even though
 * a file have been saved using the wrong file-name extension. If less than
 * [defaultMagicNumbersMaxLength] bytes was provided, some magic-numbers won't
 * be matched against.
 */
String lookupMimeType(String path, {List<int> headerBytes}) =>
    _globalResolver.lookup(path, headerBytes: headerBytes);

/**
 * MIME-type resolver class, used to customize the lookup of mime-types.
 */
class MimeTypeResolver {
  final Map<String, String> _extensionMap = {};
  final List<MagicNumber> _magicNumbers = [];
  final bool _useDefault;
  int _magicNumbersMaxLength;

  /**
   * Create a new empty [MimeTypeResolver].
   */
  MimeTypeResolver.empty()
      : _useDefault = false,
        _magicNumbersMaxLength = 0;

  /**
   * Create a new [MimeTypeResolver] containing the default scope.
   */
  MimeTypeResolver()
      : _useDefault = true,
        _magicNumbersMaxLength = DEFAULT_MAGIC_NUMBERS_MAX_LENGTH;

  /**
   * Get the maximum number of bytes required to match all magic numbers, when
   * performing [lookup] with headerBytes present.
   */
  int get magicNumbersMaxLength => _magicNumbersMaxLength;

  /**
   * Extract the extension from [path] and use that for MIME-type lookup.
   *
   * If no matching MIME-type was found, `null` is returned.
   *
   * If [headerBytes] is present, a match for known magic-numbers will be
   * performed first. This allows the correct mime-type to be found, even though
   * a file have been saved using the wrong file-name extension. If less than
   * [magicNumbersMaxLength] bytes was provided, some magic-numbers won't
   * be matched against.
   */
  String lookup(String path, {List<int> headerBytes}) {
    String result;
    if (headerBytes != null) {
      result = _matchMagic(headerBytes, _magicNumbers);
      if (result != null) return result;
      if (_useDefault) {
        result = _matchMagic(headerBytes, DEFAULT_MAGIC_NUMBERS);
        if (result != null) return result;
      }
    }
    var ext = _ext(path);
    result = _extensionMap[ext];
    if (result != null) return result;
    if (_useDefault) {
      result = defaultExtensionMap[ext];
      if (result != null) return result;
    }
    return null;
  }

  /**
   * Add a new MIME-type mapping to the [MimeTypeResolver]. If the [extension]
   * is already present in the [MimeTypeResolver], it'll be overwritten.
   */
  void addExtension(String extension, String mimeType) {
    _extensionMap[extension] = mimeType;
  }

  /**
   * Add a new magic-number mapping to the [MimeTypeResolver].
   *
   * If [mask] is present,the [mask] is used to only perform matching on
   * selective bits. The [mask] must have the same length as [bytes].
   */
  void addMagicNumber(List<int> bytes, String mimeType, {List<int> mask}) {
    if (mask != null && bytes.length != mask.length) {
      throw new ArgumentError('Bytes and mask are of different lengths');
    }
    if (bytes.length > _magicNumbersMaxLength) {
      _magicNumbersMaxLength = bytes.length;
    }
    _magicNumbers.add(new MagicNumber(mimeType, bytes, mask: mask));
  }

  static String _matchMagic(
      List<int> headerBytes, List<MagicNumber> magicNumbers) {
    for (var mn in magicNumbers) {
      if (mn.matches(headerBytes)) return mn.mimeType;
    }
    return null;
  }

  static String _ext(String path) {
    int index = path.lastIndexOf('.');
    if (index < 0 || index + 1 >= path.length) return path;
    return path.substring(index + 1).toLowerCase();
  }
}
