content: // Copyright (c)  2024  Xiaomi Corporation
  
  import "dart:io";
  
  import 'package:flutter/services.dart';
  import 'package:path_provider/path_provider.dart';
  import 'package:path/path.dart' as p;
  import 'package:sherpa_onnx/sherpa_onnx.dart' as sherpa_onnx;
  
  import './utils.dart';
  
  Future<sherpa_onnx.OfflineTts> createOfflineTts() async {
    // sherpa_onnx requires that model files are in the local disk, so we
    // need to copy all asset files to disk.
    await copyAllAssetFiles();
  
    sherpa_onnx.initBindings();
  
    // Such a design is to make it easier to build flutter APPs with
    // github actions for a variety of tts models
    //
    // See https://github.com/k2-fsa/sherpa-onnx/blob/master/scripts/flutter/generate-tts.py
    // for details
  
    String modelDir = '';
    String modelName = '';
    String voices = ''; // for Kokoro only
    String ruleFsts = '';
    String ruleFars = '';
    String lexicon = '';
    String dataDir = '';
    String dictDir = '';
  
    // You can select an example below and change it accordingly to match your
    // selected tts model
  
    // ============================================================
    // Your change starts here
    // ============================================================
  
    // Example 1:
    // modelDir = 'vits-vctk';
    // modelName = 'vits-vctk.onnx';
    // lexicon = 'lexicon.txt';
  
    // Example 2:
    // https://github.com/k2-fsa/sherpa-onnx/releases/tag/tts-models
    // https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/vits-piper-en_US-amy-low.tar.bz2
    // modelDir = 'vits-piper-en_US-amy-low';
    // modelName = 'en_US-amy-low.onnx';
    // dataDir = 'vits-piper-en_US-amy-low/espeak-ng-data';
  
    // Example 3:
    // https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/vits-icefall-zh-aishell3.tar.bz2
    // modelDir = 'vits-icefall-zh-aishell3';
    // modelName = 'model.onnx';
    // ruleFsts = 'vits-icefall-zh-aishell3/phone.fst,vits-icefall-zh-aishell3/date.fst,vits-icefall-zh-aishell3/number.fst,vits-icefall-zh-aishell3/new_heteronym.fst';
    // ruleFars = 'vits-icefall-zh-aishell3/rule.far';
    // lexicon = 'lexicon.txt';
  
    // Example 4:
    // https://k2-fsa.github.io/sherpa/onnx/tts/pretrained_models/vits.html#csukuangfj-vits-zh-hf-fanchen-c-chinese-187-speakers
    // modelDir = 'vits-zh-hf-fanchen-C';
    // modelName = 'vits-zh-hf-fanchen-C.onnx';
    // lexicon = 'lexicon.txt';
    // dictDir = 'vits-zh-hf-fanchen-C/dict';
  
    // Example 5:
    // https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/vits-coqui-de-css10.tar.bz2
    // modelDir = 'vits-coqui-de-css10';
    // modelName = 'model.onnx';
  
    // Example 6
    // https://github.com/k2-fsa/sherpa-onnx/releases/tag/tts-models
    // https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/vits-piper-en_US-libritts_r-medium.tar.bz2
    // modelDir = 'vits-piper-en_US-libritts_r-medium';
    // modelName = 'en_US-libritts_r-medium.onnx';
    // dataDir = 'vits-piper-en_US-libritts_r-medium/espeak-ng-data';
  
    // Example 7
    // https://github.com/k2-fsa/sherpa-onnx/releases/tag/tts-models
    // https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/vits-melo-tts-zh_en.tar.bz2
    // modelDir = 'vits-melo-tts-zh_en';
    // modelName = 'model.onnx';
    // lexicon = 'lexicon.txt';
    // dictDir = 'vits-melo-tts-zh_en/dict';
  
    // Example 8
    // https://k2-fsa.github.io/sherpa/onnx/tts/pretrained_models/kokoro.html#kokoro-en-v0-19-english-11-speakers
    // modelDir = 'kokoro-en-v0_19';
    // modelName = 'model.onnx';
    // voices = 'voices.bin';
    // dataDir = 'kokoro-en-v0_19/espeak-ng-data';
  
    // Example 9
    // https://k2-fsa.github.io/sherpa/onnx/tts/pretrained_models/kokoro.html
    // modelDir = 'kokoro-multi-lang-v1_0';
    // modelName = 'model.onnx';
    // voices = 'voices.bin';
    // dataDir = 'kokoro-multi-lang-v1_0/espeak-ng-data';
    // dictDir = 'kokoro-multi-lang-v1_0/dict';
    // lexicon = 'kokoro-multi-lang-v1_0/lexicon-us-en.txt,kokoro-multi-lang-v1_0/lexicon-zh.txt';
  
    // ============================================================
    // Please don't change the remaining part of this function
    // ============================================================
    if (modelName == '') {
      throw Exception(
          'You are supposed to select a model by changing the code before you run the app');
    }
  
    final Directory directory = await getApplicationSupportDirectory();
    modelName = p.join(directory.path, modelDir, modelName);
  
    if (ruleFsts != '') {
      final all = ruleFsts.split(',');
      var tmp = <String>[];
      for (final f in all) {
        tmp.add(p.join(directory.path, f));
      }
      ruleFsts = tmp.join(',');
    }
  
    if (ruleFars != '') {
      final all = ruleFars.split(',');
      var tmp = <String>[];
      for (final f in all) {
        tmp.add(p.join(directory.path, f));
      }
      ruleFars = tmp.join(',');
    }
  
    if (lexicon.contains(',')) {
      final all = lexicon.split(',');
      var tmp = <String>[];
      for (final f in all) {
        tmp.add(p.join(directory.path, f));
      }
      lexicon = tmp.join(',');
    } else if (lexicon != '') {
      lexicon = p.join(directory.path, modelDir, lexicon);
    }
  
    if (dataDir != '') {
      dataDir = p.join(directory.path, dataDir);
    }
  
    if (dictDir != '') {
      dictDir = p.join(directory.path, dictDir);
    }
  
    final tokens = p.join(directory.path, modelDir, 'tokens.txt');
    if (voices != '') {
      voices = p.join(directory.path, modelDir, voices);
    }
  
    late final sherpa_onnx.OfflineTtsVitsModelConfig vits;
    late final sherpa_onnx.OfflineTtsKokoroModelConfig kokoro;
  
    if (voices != '') {
      vits = sherpa_onnx.OfflineTtsVitsModelConfig();
      kokoro = sherpa_onnx.OfflineTtsKokoroModelConfig(
        model: modelName,
        voices: voices,
        tokens: tokens,
        dataDir: dataDir,
        dictDir: dictDir,
        lexicon: lexicon,
      );
    } else {
      vits = sherpa_onnx.OfflineTtsVitsModelConfig(
        model: modelName,
        lexicon: lexicon,
        tokens: tokens,
        dataDir: dataDir,
        dictDir: dictDir,
      );
  
      kokoro = sherpa_onnx.OfflineTtsKokoroModelConfig();
    }
  
    final modelConfig = sherpa_onnx.OfflineTtsModelConfig(
      vits: vits,
      kokoro: kokoro,
      numThreads: 2,
      debug: true,
      provider: 'cpu',
    );
  
    final config = sherpa_onnx.OfflineTtsConfig(
      model: modelConfig,
      ruleFsts: ruleFsts,
      ruleFars: ruleFars,
      maxNumSenetences: 1,
    );
    // print(config);
  
    final tts = sherpa_onnx.OfflineTts(config);
    print('tts created successfully');
  
    return tts;
  }
  