/*
 * Copyright 2011 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.gradle.api.internal.artifacts.ivyservice.modulecache;

import org.apache.ivy.core.IvyPatternHelper;
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.plugins.parser.ParserSettings;
import org.gradle.api.Action;
import org.gradle.api.artifacts.ModuleVersionIdentifier;
import org.gradle.api.internal.artifacts.DefaultModuleVersionIdentifier;
import org.gradle.api.internal.artifacts.ivyservice.IvyModuleDescriptorWriter;
import org.gradle.api.internal.artifacts.ivyservice.ivyresolve.IvyContextualiser;
import org.gradle.api.internal.artifacts.ivyservice.ivyresolve.ModuleVersionRepository;
import org.gradle.api.internal.artifacts.ivyservice.ivyresolve.parser.IvyXmlModuleDescriptorParser;
import org.gradle.api.internal.filestore.FileStoreEntry;
import org.gradle.api.internal.filestore.PathKeyFileStore;
import org.gradle.internal.UncheckedException;

import java.io.File;
import java.net.URL;
import java.util.Collections;

public class ModuleDescriptorStore {

    private static final String DESCRIPTOR_ARTIFACT_PATTERN =
            "module-metadata/[organisation]/[module](/[branch])/[revision]/[resolverId].ivy.xml";

    private final IvyXmlModuleDescriptorParser parser;
    private final PathKeyFileStore pathKeyFileStore;
    private final IvyModuleDescriptorWriter ivyModuleDescriptorWriter;

    public ModuleDescriptorStore(PathKeyFileStore pathKeyFileStore, IvyModuleDescriptorWriter ivyModuleDescriptorWriter, IvyXmlModuleDescriptorParser ivyXmlModuleDescriptorParser) {
        this.pathKeyFileStore = pathKeyFileStore;
        this.ivyModuleDescriptorWriter = ivyModuleDescriptorWriter;
        parser = ivyXmlModuleDescriptorParser;
    }

    public ModuleDescriptor getModuleDescriptor(ModuleVersionRepository repository, ModuleVersionIdentifier moduleVersionIdentifier) {
        String filePath = getFilePath(repository, moduleVersionIdentifier);
        final FileStoreEntry fileStoreEntry = pathKeyFileStore.get(filePath);
        if (fileStoreEntry != null) {
            return parseModuleDescriptorFile(fileStoreEntry.getFile());
        }
        return null;
    }

    public FileStoreEntry putModuleDescriptor(ModuleVersionRepository repository, final ModuleDescriptor moduleDescriptor) {
        final ModuleRevisionId moduleRevisionId = moduleDescriptor.getModuleRevisionId();
        final ModuleVersionIdentifier moduleVersionIdentifier = new DefaultModuleVersionIdentifier(moduleRevisionId.getOrganisation(),
                moduleRevisionId.getName(),
                moduleRevisionId.getRevision());
        String filePath = getFilePath(repository, moduleVersionIdentifier);
        return pathKeyFileStore.add(filePath, new Action<File>() {
            public void execute(File moduleDescriptorFile) {
                try {
                    ivyModuleDescriptorWriter.write(moduleDescriptor, moduleDescriptorFile);
                } catch (Exception e) {
                    throw UncheckedException.throwAsUncheckedException(e);
                }
            }
        });
    }

    private ModuleDescriptor parseModuleDescriptorFile(File moduleDescriptorFile) {
        ParserSettings settings = IvyContextualiser.getIvyContext().getSettings();
        try {
            URL result = moduleDescriptorFile.toURI().toURL();
            return parser.parseDescriptor(settings, result, false);
        } catch (Exception e) {
            throw UncheckedException.throwAsUncheckedException(e);
        }
    }

    private String getFilePath(ModuleVersionRepository repository, ModuleVersionIdentifier moduleVersionIdentifier) {
        String resolverId = repository.getId();


        return IvyPatternHelper.substitute(DESCRIPTOR_ARTIFACT_PATTERN,
                moduleVersionIdentifier.getGroup(),
                moduleVersionIdentifier.getName(),
                null,
                moduleVersionIdentifier.getVersion(),
                "ivy",
                "ivy",
                "ivy",
                null,
                null,
                Collections.emptyMap(),
                Collections.singletonMap("resolverId", resolverId));
    }
}
@@ -680,53 +680,8 @@
 e;%0A%0A
-import org.apache.ivy.core.IvyPatternHelper;%0A
 impo
@@ -1565,38 +1565,8 @@
 URL;
-%0Aimport java.util.Collections;
 %0A%0Apu
@@ -1605,169 +1605,8 @@
  %7B%0A%0A
-    private static final String DESCRIPTOR_ARTIFACT_PATTERN =%0A            %22module-metadata/%5Borganisation%5D/%5Bmodule%5D(/%5Bbranch%5D)/%5Brevision%5D/%5BresolverId%5D.ivy.xml%22;%0A%0A
     
@@ -4058,137 +4058,67 @@
     
-String resolverId = repository.getId();%0A%0A%0A        return IvyPatternHelper.substitute(DESCRIPTOR_ARTIFACT_PATTERN,%0A               
+return String.format(%22module-metadata/%25s/%25s/%25s/%25s.ivy.xml%22,
  mod
@@ -4149,32 +4149,16 @@
 Group(),
-%0A               
  moduleV
@@ -4188,303 +4188,64 @@
 e(),
-%0A                null,%0A                moduleVersionIdentifier.getVersion(),%0A                %22ivy%22,%0A                %22ivy%22,%0A                %22ivy%22,%0A                null,%0A                null,%0A                Collections.emptyMap(),%0A                Collections.singletonMap(%22resolverId%22, resolver
+ moduleVersionIdentifier.getVersion(), repository.get
 Id
+(
 ));%0A

simplify filepath calculation; use String.format instead of IvyPatternHelper & friends; remove unused 'branch' in path pattern.