using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
  class Program
  {

    static int upgradeSerialList(List<string> allserials)
    {
      string errmsg = "";
      foreach (string serial in allserials) {
        YModule module = YModule.FindModule(serial);
        string product = module.get_productName();
        string current = module.get_firmwareRelease();

        // check if a new firmare is available on yoctopuce.com
        string newfirm = module.checkFirmware("www.yoctopuce.com", true);
        if (newfirm == "") {
          Console.WriteLine(product + " " + serial + "(rev=" + current + ") is up to date");
        } else {
          Console.WriteLine(product + " " + serial + "(rev=" + current +
                            ") need be updated with firmare : ");
          Console.WriteLine("    " + newfirm);
          // execute the firmware upgrade
          YFirmwareUpdate update = module.updateFirmware(newfirm);
          int status = update.startUpdate();
          do {
            int newstatus = update.get_progress();
            if (newstatus != status)
              Console.WriteLine(newstatus + "% " + update.get_progressMessage());
            YAPI.Sleep(500, ref errmsg);
            status = newstatus;
          } while (status < 100 && status >= 0);
          if (status < 0) {
            Console.WriteLine("Firmware Update failed: " + update.get_progressMessage());
            Environment.Exit(1);
          } else {
            if (module.isOnline()) {
              Console.WriteLine(status + "% Firmware Updated Successfully!");
            } else {
              Console.WriteLine(status + " Firmware Update failed: module " + serial + "is not online");
              Environment.Exit(1);
            }
          }
        }
      }
      return 0;
    }

    static void Main(string[] args)
    {
      int i;
      List<string> hubs = new List<string>();
      List<string> shield = new List<string>();
      List<string> devices = new List<string>();

      string errmsg = "";


      if (YAPI.RegisterHub("usb", ref errmsg) != YAPI.SUCCESS) {
        Console.WriteLine("RegisterHub error : " + errmsg);
        Environment.Exit(0);
      }

      for (i = 0; i < args.Length; i++) {
        Console.WriteLine("Update module connected to hub " + args[i]);
        if (YAPI.RegisterHub(args[i], ref errmsg) != YAPI.SUCCESS) {
          Console.WriteLine("RegisterHub error: " + errmsg);
          Environment.Exit(1);
        }
      }
      //fist step construct the list of all hub /shield and devices connected
      YModule module = YModule.FirstModule();
      while (module != null) {
        string product = module.get_productName();
        string serial = module.get_serialNumber();
        if (product == "YoctoHub-Shield") {
          shield.Add(serial);
        } else if (product.StartsWith("YoctoHub")) {
          hubs.Add(serial);
        } else if (product != "VirtualHub") {
          devices.Add(serial);
        }
        module = module.nextModule();
      }
      // fist upgrades all Hubs...
      upgradeSerialList(hubs);
      // ... then all shield..
      upgradeSerialList(shield);
      // ... and finaly all devices
      upgradeSerialList(devices);
      Console.WriteLine("All devices are now up to date");
      YAPI.FreeAPI();
    }
  }
}
