// Copyright 2017 The Fuchsia 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:async';
import 'dart:convert';
import 'dart:io';

import 'asset.dart';

/// Reads the configuration from [fileName].
Future<List<Asset>> readConfig(String fileName) async {
  File file = new File(fileName);

  if (!file.existsSync()) {
    throw new ArgumentError.value(fileName, 'fileName', 'File does not exist');
  }

  return _convertAssetList(json.decode(await file.readAsString()));
}

String _convertString(Object json) {
  if (json is! String) {
    throw const FormatException('Config file is malformed: string expected');
  }

  return json;
}

bool _convertBool(Object json) {
  if (json is! String || (json != 'true' && json != 'false')) {
    throw const FormatException(
        'Config file is malformed: "true" or "false" expected');
  }

  return json == 'true';
}

Asset _convertAsset(Object json) {
  if (json is! Map) {
    throw const FormatException('Config file is malformed: object expected');
  }

  Map<String, Object> jsonMap = json;

  Uri uri;
  AssetType type;
  String title;
  String artist;
  String album;
  List<Asset> children;
  bool loop = false;

  jsonMap.forEach((String key, Object value) {
    switch (key) {
      case 'uri':
      case 'url':
        try {
          uri = Uri.parse(_convertString(value));
        } on FormatException {
          throw new FormatException('Config file is malformed: bad URI $value');
        }
        break;
      case 'type':
        switch (_convertString(value)) {
          case 'movie':
            type = AssetType.movie;
            break;
          case 'song':
            type = AssetType.song;
            break;
          case 'playlist':
            type = AssetType.playlist;
            break;
          default:
            throw new FormatException(
                'Config file is malformed: $value is not a valid type');
        }
        break;
      case 'title':
        title = _convertString(value);
        break;
      case 'artist':
        artist = _convertString(value);
        break;
      case 'album':
        album = _convertString(value);
        break;
      case 'children':
        children = _convertAssetList(value);
        break;
      case 'loop':
        loop = _convertBool(value);
        break;
    }
  });

  if (type == null) {
    // Try to infer the type.
    if (uri == null) {
      if (children != null) {
        type = AssetType.playlist;
      }
    } else if (_isMovieUri(uri)) {
      type = AssetType.movie;
    } else if (_isMusicUri(uri)) {
      type = AssetType.song;
    }
  }

  if (type == null) {
    throw const FormatException(
        'Config file is malformed: asset type was not specified and cannot be'
        ' inferred');
  }

  switch (type) {
    case AssetType.movie:
      _checkNotNull(type, uri, 'a URI');
      _checkNull(type, children, 'children');
      return new Asset.movie(
        uri: uri,
        title: title,
        artist: artist,
        album: album,
        loop: loop,
      );

    case AssetType.song:
      _checkNotNull(type, uri, 'a URI');
      _checkNull(type, children, 'children');
      return new Asset.song(
        uri: uri,
        title: title,
        artist: artist,
        album: album,
        loop: loop,
      );

    case AssetType.playlist:
      _checkNull(type, uri, 'a URI');
      _checkNotNull(type, children, 'children');
      _checkNull(type, artist, 'artist name');
      _checkNull(type, album, 'album name');
      if (children.isEmpty) {
        throw const FormatException(
            'Config file is malformed: a playlist must have at least one child');
      }
      if (!children.every(
          (Asset c) => c.type == AssetType.movie || c.type == AssetType.song)) {
        throw const FormatException(
            'Config file is malformed: playlist children must be songs or movies');
      }
      return new Asset.playlist(
        title: title,
        children: children,
        loop: loop,
      );

    default:
      throw new FormatException('Unknown asset type: $type');
  }
}

void _checkNotNull(AssetType type, Object value, String name) {
  if (value == null) {
    throw new FormatException(
        'Config file is malformed: a $type must have $name');
  }
}

void _checkNull(AssetType type, Object value, String name) {
  if (value != null) {
    throw new FormatException(
        'Config file is malformed: a $type must not have $name');
  }
}

List<Asset> _convertAssetList(Object json) {
  if (json is! List) {
    throw const FormatException('Config file is malformed: array expected');
  }

  List<Object> jsonList = json;

  List<Asset> list = <Asset>[];

  for (Object item in jsonList) {
    Asset asset = _convertAsset(item);
    if (asset != null) {
      list.add(asset);
    }
  }

  return list;
}

bool _isMovieUri(Uri uri) {
  switch (_extension(uri)) {
    case 'ogv':
    case 'mp4':
    case 'vp8':
    case 'vp9':
    case 'mkv':
    case 'mov':
    case 'webm':
      return true;
  }

  return false;
}

bool _isMusicUri(Uri uri) {
  switch (_extension(uri)) {
    case 'ogg':
    case 'wav':
    case 'mp3':
    case 'flac':
      return true;
  }

  return false;
}

String _extension(Uri uri) {
  String lastSegment = uri.pathSegments.last;
  int index = lastSegment.lastIndexOf('.');
  return index == -1 ? null : lastSegment.substring(index + 1);
}
