private static Asset CreateAsset(string assetName, SnipeAccess access, StartOption startOption, Config config,
                                         SystemInfo info)
        {
            var isClient   = startOption.IsClient ?? info.IsClient;
            var isNotebook = startOption.IsNotebook ?? info.IsNotebook;

            var manufacturer = (startOption.ManufacturerId.HasValue
                                   ? access.Get <Manufacturer>(startOption.ManufacturerId.Value)
                                   : access.Get <Manufacturer>(info.Manufacturer)) ??
                               access.Create(new Manufacturer {
                Name = info.Manufacturer
            });

            var model = startOption.ModelId.HasValue
                ? access.Get <Model>(startOption.ModelId.Value)
                : access.Get <Model>(info.Model);

            if (model == null)
            {
                var categoryName = isClient ? isNotebook ? "Notebook" : "Desktop" : "Server";
                var category     =
                    access.Get <Category>(categoryName) ??
                    access.Create(new Category {
                    Name = categoryName, Type = "asset"
                });

                model = new Model {
                    Name = info.Model, Manufacturer = manufacturer, Category = category
                };
                model = access.Create(model);
            }

            StatusLabel statusLabel;

            if (config.StatusLabelId > 0)
            {
                statusLabel = access.Get <StatusLabel>(config.StatusLabelId);
            }
            else
            {
                var labels = access.Get <StatusLabel>();
                statusLabel = labels.FirstOrDefault(l => l.Type == "deployable");
            }

            return(new Asset
            {
                Manufacturer = manufacturer,
                Model = model,
                Name = assetName,
                Serial = info.SerialNumber,
                AssetTag = startOption.NewAssetTag ?? string.Empty,
                StatusLabel = statusLabel
            });
        }
        private static int CreateOrUpdateAsset(StartOption startOption)
        {
            var config = GetConfig(startOption);

            var access = new SnipeAccess
            {
                ApiToken = config.ApiToken,
                Uri      = config.Uri
            };

            var provider = new WindowsSystemInfoProvider();
            var info     = provider.GetSystemInfo();

            var assetName = string.IsNullOrEmpty(startOption.AssetName) ? info.Hostname : startOption.AssetName;
            var asset     = access.Get <Asset>(assetName);

            Func <Asset, Asset> saveAsset;

            if (asset == null)
            {
                asset = CreateAsset(assetName, access, startOption, config, info);

                saveAsset = a => access.Create(a);
            }
            else
            {
                saveAsset = a => access.Update(a);
            }

            TryUpdateCompany(asset, access, config);

            TryUpdateLocation(asset, access, config);

            TryUpdateCustomFields(asset, access, info);

            asset = saveAsset(asset);

            if (asset == null)
            {
                return(1);
            }

            Console.Out.Write(asset.AssetTag);

            return(0);
        }