class ResourceTaggingManager {

    public Boolean tagResource(final String resourceId, final Map<String, Object> clientMap, AWSService serviceType,
            Map<String, String> pacTag) throws Exception {

        switch (serviceType) {
        case S3: {
            try {

                AmazonS3 s3Client = (AmazonS3) clientMap.get("client");
                BucketTaggingConfiguration bucketTaggingConfiguration = s3Client
                        .getBucketTaggingConfiguration(resourceId);
                if (bucketTaggingConfiguration == null) {
                    saveTags(resourceId, new BucketTaggingConfiguration(Collections.singletonList(new TagSet(pacTag))),
                            s3Client);
                } else {
                    List<TagSet> existingTargets = bucketTaggingConfiguration.getAllTagSets();
                    Map<String, String> existingTags = existingTargets.get(0).getAllTags();
                    Map<String, String> allTags = Maps.newHashMap();

                    if (bucketAlreadyTaggedAndTagValueNotAltered(existingTags, pacTag))
                        return Boolean.TRUE;

                    allTags.putAll(existingTags);
                    allTags.putAll(pacTag);
                    bucketTaggingConfiguration.setTagSets(existingTargets);
                    saveTags(resourceId,
                            new BucketTaggingConfiguration(Collections.singletonList(new TagSet(allTags))), s3Client);
                }
                return Boolean.TRUE;
            } catch (Exception exception) {
                logger.error("error tagging bucekt - > " + resourceId, exception);
                throw exception;
            }


        }
        case EC2: {
            return setEC2VolumeTag(resourceId, clientMap, pacTag);
        }
        case SNAPSHOT: {
            return setEC2VolumeTag(resourceId, clientMap, pacTag);

        }
        case VOLUME: {
            return setEC2VolumeTag(resourceId, clientMap, pacTag);

        }
        case RDSDB: {
            return setRDSDBTag(resourceId,clientMap,pacTag);

        }
        case ELASTICSEARCH:{
            return setElasticSearchTag(resourceId,clientMap,pacTag);
        }
        case EFS:{
            return setEFSTag(resourceId,clientMap,pacTag);
        }
        case REDSHIFT:{
            return setRedshiftTag(resourceId,clientMap,pacTag);
        }
        default:
            throw new OperationNotPermittedException("this resource tagging is not imlemented yet");
        }
    }

}