// 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 = 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 ArgumentError('Bytes and mask are of different lengths');
    }
    if (bytes.length > _magicNumbersMaxLength) {
      _magicNumbersMaxLength = bytes.length;
    }
    _magicNumbers.add(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) {
    var index = path.lastIndexOf('.');
    if (index < 0 || index + 1 >= path.length) return path;
    return path.substring(index + 1).toLowerCase();
  }
}
