// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

import 'dart:math';

import 'package:http/http.dart' as http;
import 'package:type_utils_example/error.dart';
import 'package:type_utils_example/todo.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart';

Future<TodoModel> get(String url) async {
  final res = await http.get(Uri.parse(url));
  final todo = TodoModel.fromJson(res.body);
  return todo;
}

Future<Result<TodoModel, AppError>> requestTodo() async => Result.tryCatchAsync(
      () => get('https://jsonplaceholder.typicode.com/todos/1'),
      (error) => ServerError('Error while getting todo'),
    );

Future<Result<TodoModel, AppError>> requestBadTodo() async =>
    Result.tryCatchAsync(
      () => get('https://jsonplaceholder.typicode.com/todos/123897'),
      (error) => ServerError('Error while getting todo'),
    );

Future<void> main() async {
  final Result<TodoModel, AppError> todo1 = await requestTodo();
  todo1.either(print, print);

  final Result<TodoModel, AppError> todo2 = await requestBadTodo();
  todo2.either(print, print);

  final Option<int> rand = Option.ofNullable(Random().nextBool() ? null : 10);

  print(
    "`rand` is${rand.isNull ? "" : " not"} null, "
    "so it's value is ${rand.orElse(15)}",
  );

  // Ok, `orElse` is equivalent to ?? but the Option is useful for match pattern
  rand.match((value) {
    print('Value is: $value');
  }, () {
    print('Rand is null');
  });

  print('`rand` contains 10 ? => ${rand.contains(10)}');
}
