// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';

import 'constants.dart';
import 'resource_record.dart';

// Offsets into the header. See https://tools.ietf.org/html/rfc1035.
const int _kIdOffset = 0;
const int _kFlagsOffset = 2;
const int _kQdcountOffset = 4;
const int _kAncountOffset = 6;
const int _kNscountOffset = 8;
const int _kArcountOffset = 10;
const int _kHeaderSize = 12;

/// Processes a DNS query name into a list of parts.
///
/// Will attempt to append 'local' if the name is something like '_http._tcp',
/// and '._tcp.local' if name is something like '_http'.
List<String> processDnsNameParts(String name) {
  final List<String> parts = name.split('.');
  if (parts.length == 1) {
    return <String>[parts[0], '_tcp', 'local'];
  } else if (parts.length == 2 && parts[1].startsWith('_')) {
    return <String>[parts[0], parts[1], 'local'];
  }

  return parts;
}

/// Encode an mDNS query packet.
///
/// The [type] parameter must be a valid [ResourceRecordType] value. The
/// [multicast] parameter must not be null.
///
/// This is a low level API; most consumers should prefer
/// [ResourceRecordQuery.encode], which offers some convenience wrappers around
/// selecting the correct [type] and setting the [name] parameter correctly.
List<int> encodeMDnsQuery(
  String name, {
  int type = ResourceRecordType.addressIPv4,
  bool multicast = true,
}) {
  assert(ResourceRecordType.debugAssertValid(type));

  final List<String> nameParts = processDnsNameParts(name);
  final List<List<int>> rawNameParts =
      nameParts.map<List<int>>((String part) => utf8.encode(part)).toList();

  // Calculate the size of the packet.
  int size = _kHeaderSize;
  for (int i = 0; i < rawNameParts.length; i++) {
    size += 1 + rawNameParts[i].length;
  }

  size += 1; // End with empty part
  size += 4; // Trailer (QTYPE and QCLASS).
  final Uint8List data = Uint8List(size);
  final ByteData packetByteData = ByteData.view(data.buffer);
  // Query identifier - just use 0.
  packetByteData.setUint16(_kIdOffset, 0);
  // Flags - 0 for query.
  packetByteData.setUint16(_kFlagsOffset, 0);
  // Query count.
  packetByteData.setUint16(_kQdcountOffset, 1);
  // Number of answers - 0 for query.
  packetByteData.setUint16(_kAncountOffset, 0);
  // Number of name server records - 0 for query.
  packetByteData.setUint16(_kNscountOffset, 0);
  // Number of resource records - 0 for query.
  packetByteData.setUint16(_kArcountOffset, 0);
  int offset = _kHeaderSize;
  for (int i = 0; i < rawNameParts.length; i++) {
    data[offset++] = rawNameParts[i].length;
    data.setRange(offset, offset + rawNameParts[i].length, rawNameParts[i]);
    offset += rawNameParts[i].length;
  }

  data[offset] = 0; // Empty part.
  offset++;
  packetByteData.setUint16(offset, type); // QTYPE.
  offset += 2;
  packetByteData.setUint16(
      offset,
      ResourceRecordClass.internet |
          (multicast ? QuestionType.multicast : QuestionType.unicast));

  return data;
}

/// Result of reading a Fully Qualified Domain Name (FQDN).
class _FQDNReadResult {
  /// Creates a new FQDN read result.
  _FQDNReadResult(this.fqdnParts, this.bytesRead);

  /// The raw parts of the FQDN.
  final List<String> fqdnParts;

  /// The bytes consumed from the packet for this FQDN.
  final int bytesRead;

  /// Returns the Fully Qualified Domain Name.
  String get fqdn => fqdnParts.join('.');

  @override
  String toString() => fqdn;
}

/// Reads a FQDN from raw packet data.
String readFQDN(List<int> packet, [int offset = 0]) {
  final Uint8List data =
      packet is Uint8List ? packet : Uint8List.fromList(packet);
  final ByteData byteData = ByteData.view(data.buffer);

  return _readFQDN(data, byteData, offset, data.length).fqdn;
}

// Read a FQDN at the given offset. Returns a pair with the FQDN
// parts and the number of bytes consumed.
//
// If decoding fails (e.g. due to an invalid packet) `null` is returned.
_FQDNReadResult _readFQDN(
    Uint8List data, ByteData byteData, int offset, int length) {
  void checkLength(int required) {
    if (length < required) {
      throw MDnsDecodeException(required);
    }
  }

  final List<String> parts = <String>[];
  final int prevOffset = offset;
  while (true) {
    // At least one byte is required.
    checkLength(offset + 1);

    // Check for compressed.
    if (data[offset] & 0xc0 == 0xc0) {
      // At least two bytes are required for a compressed FQDN.
      checkLength(offset + 2);

      // A compressed FQDN has a new offset in the lower 14 bits.
      final _FQDNReadResult result = _readFQDN(
          data, byteData, byteData.getUint16(offset) & ~0xc000, length);
      parts.addAll(result.fqdnParts);
      offset += 2;
      break;
    } else {
      // A normal FQDN part has a length and a UTF-8 encoded name
      // part. If the length is 0 this is the end of the FQDN.
      final int partLength = data[offset];
      offset++;
      if (partLength > 0) {
        checkLength(offset + partLength);
        final Uint8List partBytes =
            Uint8List.view(data.buffer, offset, partLength);
        offset += partLength;
        // According to the RFC, this is supposed to be utf-8 encoded, but
        // we should continue decoding even if it isn't to avoid dropping the
        // rest of the data, which might still be useful.
        parts.add(utf8.decode(partBytes, allowMalformed: true));
      } else {
        break;
      }
    }
  }
  return _FQDNReadResult(parts, offset - prevOffset);
}

/// Decode an mDNS query packet.
///
/// If decoding fails (e.g. due to an invalid packet), `null` is returned.
///
/// See https://tools.ietf.org/html/rfc1035 for format.
ResourceRecordQuery? decodeMDnsQuery(List<int> packet) {
  final int length = packet.length;
  if (length < _kHeaderSize) {
    return null;
  }

  final Uint8List data =
      packet is Uint8List ? packet : Uint8List.fromList(packet);
  final ByteData packetBytes = ByteData.view(data.buffer);

  // Check whether it's a query.
  final int flags = packetBytes.getUint16(_kFlagsOffset);
  if (flags != 0) {
    return null;
  }
  final int questionCount = packetBytes.getUint16(_kQdcountOffset);
  if (questionCount == 0) {
    return null;
  }

  final _FQDNReadResult fqdn =
      _readFQDN(data, packetBytes, _kHeaderSize, data.length);

  int offset = _kHeaderSize + fqdn.bytesRead;
  final int type = packetBytes.getUint16(offset);
  offset += 2;
  final int queryType = packetBytes.getUint16(offset) & 0x8000;
  return ResourceRecordQuery(type, fqdn.fqdn, queryType);
}

/// Decode an mDNS response packet.
///
/// If decoding fails (e.g. due to an invalid packet) `null` is returned.
///
/// See https://tools.ietf.org/html/rfc1035 for the format.
List<ResourceRecord>? decodeMDnsResponse(List<int> packet) {
  final int length = packet.length;
  if (length < _kHeaderSize) {
    return null;
  }

  final Uint8List data =
      packet is Uint8List ? packet : Uint8List.fromList(packet);
  final ByteData packetBytes = ByteData.view(data.buffer);

  final int answerCount = packetBytes.getUint16(_kAncountOffset);
  final int authorityCount = packetBytes.getUint16(_kNscountOffset);
  final int additionalCount = packetBytes.getUint16(_kArcountOffset);
  final int remainingCount = answerCount + authorityCount + additionalCount;

  if (remainingCount == 0) {
    return null;
  }

  final int questionCount = packetBytes.getUint16(_kQdcountOffset);
  int offset = _kHeaderSize;

  void checkLength(int required) {
    if (length < required) {
      throw MDnsDecodeException(required);
    }
  }

  ResourceRecord? readResourceRecord() {
    // First read the FQDN.
    final _FQDNReadResult result = _readFQDN(data, packetBytes, offset, length);
    final String fqdn = result.fqdn;
    offset += result.bytesRead;
    checkLength(offset + 2);
    final int type = packetBytes.getUint16(offset);
    offset += 2;
    // The first bit of the rrclass field is set to indicate that the answer is
    // unique and the querier should flush the cached answer for this name
    // (RFC 6762, Sec. 10.2). We ignore it for now since we don't cache answers.
    checkLength(offset + 2);
    final int resourceRecordClass = packetBytes.getUint16(offset) & 0x7fff;

    if (resourceRecordClass != ResourceRecordClass.internet) {
      // We do not support other classes.
      return null;
    }

    offset += 2;
    checkLength(offset + 4);
    final int ttl = packetBytes.getInt32(offset);
    offset += 4;

    checkLength(offset + 2);
    final int readDataLength = packetBytes.getUint16(offset);
    offset += 2;
    final int validUntil = DateTime.now().millisecondsSinceEpoch + ttl * 1000;
    switch (type) {
      case ResourceRecordType.addressIPv4:
        checkLength(offset + readDataLength);
        final StringBuffer addr = StringBuffer();
        final int stop = offset + readDataLength;
        addr.write(packetBytes.getUint8(offset));
        offset++;
        for (; offset < stop; offset++) {
          addr.write('.');
          addr.write(packetBytes.getUint8(offset));
        }
        return IPAddressResourceRecord(fqdn, validUntil,
            address: InternetAddress(addr.toString()));
      case ResourceRecordType.addressIPv6:
        checkLength(offset + readDataLength);
        final StringBuffer addr = StringBuffer();
        final int stop = offset + readDataLength;
        addr.write(packetBytes.getUint16(offset).toRadixString(16));
        offset += 2;
        for (; offset < stop; offset += 2) {
          addr.write(':');
          addr.write(packetBytes.getUint16(offset).toRadixString(16));
        }
        return IPAddressResourceRecord(
          fqdn,
          validUntil,
          address: InternetAddress(addr.toString()),
        );
      case ResourceRecordType.service:
        checkLength(offset + 2);
        final int priority = packetBytes.getUint16(offset);
        offset += 2;
        checkLength(offset + 2);
        final int weight = packetBytes.getUint16(offset);
        offset += 2;
        checkLength(offset + 2);
        final int port = packetBytes.getUint16(offset);
        offset += 2;
        final _FQDNReadResult result =
            _readFQDN(data, packetBytes, offset, length);
        offset += result.bytesRead;
        return SrvResourceRecord(
          fqdn,
          validUntil,
          target: result.fqdn,
          port: port,
          priority: priority,
          weight: weight,
        );
      case ResourceRecordType.serverPointer:
        checkLength(offset + readDataLength);
        final _FQDNReadResult result =
            _readFQDN(data, packetBytes, offset, length);
        offset += readDataLength;
        return PtrResourceRecord(
          fqdn,
          validUntil,
          domainName: result.fqdn,
        );
      case ResourceRecordType.text:
        checkLength(offset + readDataLength);
        // The first byte of the buffer is the length of the first string of
        // the TXT record. Further length-prefixed strings may follow. We
        // concatenate them with newlines.
        final StringBuffer strings = StringBuffer();
        int index = 0;
        while (index < readDataLength) {
          final int txtLength = data[offset + index];
          index++;
          if (txtLength == 0) {
            continue;
          }
          final String text = utf8.decode(
            Uint8List.view(data.buffer, offset + index, txtLength),
            allowMalformed: true,
          );
          strings.writeln(text);
          index += txtLength;
        }
        offset += readDataLength;
        return TxtResourceRecord(fqdn, validUntil, text: strings.toString());
      default:
        checkLength(offset + readDataLength);
        offset += readDataLength;
        return null;
    }
  }

  // This list can't be fixed length right now because we might get
  // resource record types we don't support, and consumers expect this list
  // to not have null entries.
  final List<ResourceRecord> result = <ResourceRecord>[];

  try {
    for (int i = 0; i < questionCount; i++) {
      final _FQDNReadResult result =
          _readFQDN(data, packetBytes, offset, length);
      offset += result.bytesRead;
      checkLength(offset + 4);
      offset += 4;
    }
    for (int i = 0; i < remainingCount; i++) {
      final ResourceRecord? record = readResourceRecord();
      if (record != null) {
        result.add(record);
      }
    }
  } on MDnsDecodeException {
    // If decoding fails return null.
    return null;
  }
  return result;
}

/// This exception is thrown by the decoder when the packet is invalid.
class MDnsDecodeException implements Exception {
  /// Creates a new MDnsDecodeException, indicating an error in decoding at the
  /// specified [offset].
  ///
  /// The [offset] parameter should not be null.
  const MDnsDecodeException(this.offset);

  /// The offset in the packet at which the exception occurred.
  final int offset;

  @override
  String toString() => 'Decoding error at $offset';
}
