/** {@inheritDoc} */
  @Override
  public Long createFarm(Long userNo, String farmName, String comment) {
    // 引数チェック
    if (userNo == null) {
      throw new AutoApplicationException("ECOMMON-000003", "userNo");
    }
    if (farmName == null || farmName.length() == 0) {
      throw new AutoApplicationException("ECOMMON-000003", "farmName");
    }

    // 形式チェック
    if (!Pattern.matches("^[0-9a-z]|[0-9a-z][0-9a-z-]*[0-9a-z]$", farmName)) {
      throw new AutoApplicationException("ECOMMON-000012", "farmName");
    }

    // TODO: 長さチェック

    // ファーム名の一意チェック
    Farm checkFarm = farmDao.readByFarmName(farmName);
    if (checkFarm != null) {
      // 同名のファームが存在する場合
      throw new AutoApplicationException("ESERVICE-000201", farmName);
    }

    // ファームのドメイン名
    // TODO: 設定値の取得方法をうまくする
    String domainName = farmName + "." + Config.getProperty("dns.domain");

    // ファームの作成
    Farm farm = new Farm();
    farm.setFarmName(farmName);
    farm.setUserNo(userNo);
    farm.setComment(comment);
    farm.setDomainName(domainName);
    farm.setScheduled(false);
    farm.setComponentProcessing(false);
    farmDao.create(farm);

    // ファームごとのホストグループ作成
    Boolean useZabbix = BooleanUtils.toBooleanObject(Config.getProperty("zabbix.useZabbix"));
    if (BooleanUtils.isTrue(useZabbix)) {
      zabbixHostProcess.createFarmHostgroup(farm.getFarmNo());
    }

    // VMware関連情報の作成
    List<Platform> platforms = platformDao.readAll();
    for (Platform platform : platforms) {
      if ("vmware".equals(platform.getPlatformType()) == false) {
        continue;
      }

      if (vmwareKeyPairDao.countByUserNoAndPlatformNo(userNo, platform.getPlatformNo()) > 0) {
        // 空いているVLANを取得
        VmwareNetwork publicNetwork = null;
        VmwareNetwork privateNetwork = null;
        List<VmwareNetwork> vmwareNetworks =
            vmwareNetworkDao.readByPlatformNo(platform.getPlatformNo());
        for (VmwareNetwork vmwareNetwork : vmwareNetworks) {
          if (vmwareNetwork.getFarmNo() != null) {
            continue;
          }
          if (BooleanUtils.isTrue(vmwareNetwork.getPublicNetwork())) {
            if (publicNetwork == null) {
              publicNetwork = vmwareNetwork;
            }
          } else {
            if (privateNetwork == null) {
              privateNetwork = vmwareNetwork;
            }
          }
        }

        // VLANを割り当て
        if (publicNetwork != null) {
          publicNetwork.setFarmNo(farm.getFarmNo());
          vmwareNetworkDao.update(publicNetwork);
        }
        if (privateNetwork != null) {
          privateNetwork.setFarmNo(farm.getFarmNo());
          vmwareNetworkDao.update(privateNetwork);
        }
      }
    }

    // イベントログ出力
    eventLogger.log(
        EventLogLevel.INFO,
        farm.getFarmNo(),
        farmName,
        null,
        null,
        null,
        null,
        "FarmCreate",
        null,
        null,
        null);

    return farm.getFarmNo();
  }