/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.apache.sling.servlets.post.impl.operations;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.jcr.RepositoryException;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

import org.apache.commons.io.IOUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.ModifiableValueMap;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.commons.testing.sling.MockResourceResolver;
import org.apache.sling.servlets.post.AbstractPostResponse;
import org.apache.sling.servlets.post.Modification;
import org.apache.sling.servlets.post.PostResponse;
import org.apache.sling.servlets.post.impl.helper.MockSlingHttpServlet3Request;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class StreamingUploadOperationTest {

    private static final Logger LOG = LoggerFactory.getLogger(StreamingUploadOperationTest.class);
    private StreamedUploadOperation streamedUplodOperation;

    @Before
    public void before() {
        streamedUplodOperation = new StreamedUploadOperation();

    }

    @After
    public void after() {

    }

    @Test
    public void test() throws PersistenceException, RepositoryException, UnsupportedEncodingException {
        List<Modification> changes = new ArrayList<>();
        PostResponse response = new AbstractPostResponse() {
            @Override
            protected void doSend(HttpServletResponse response) throws IOException {

            }

            @Override
            public void onChange(String type, String... arguments) {

            }

            @Override
            public String getPath() {
                return "/test/upload/location";
            }
        };

        List<Part> partsList = new ArrayList<>();
        partsList.add(new MockPart("formfield1", null, null, 0, new ByteArrayInputStream("testformfield1".getBytes("UTF-8")), Collections.EMPTY_MAP));
        partsList.add(new MockPart("formfield2", null, null, 0, new ByteArrayInputStream("testformfield2".getBytes("UTF-8")), Collections.EMPTY_MAP));
        partsList.add(new MockPart("test1.txt", "text/plain", "test1bad.txt", 4, new ByteArrayInputStream("test".getBytes("UTF-8")), Collections.EMPTY_MAP));
        partsList.add(new MockPart("*", "text/plain2", "test2.txt", 8, new ByteArrayInputStream("test1234".getBytes("UTF-8")), Collections.EMPTY_MAP));
        partsList.add(new MockPart("badformfield2", null, null, 0, new ByteArrayInputStream("testbadformfield2".getBytes("UTF-8")), Collections.EMPTY_MAP));
        final Iterator<Part> partsIterator = partsList.iterator();
        final Map<String, Resource> repository = new HashMap<>();
        final ResourceResolver resourceResolver = new MockResourceResolver() {
            @Override
            public Resource getResource(String path) {

                Resource resource = repository.get(path);

                if ( resource == null ) {
                    if ( "/test/upload/location".equals(path)) {
                        resource =  new MockRealResource(this, path, "sling:Folder");
                        repository.put(path,resource);
                        LOG.debug("Created {} ", path);

                    }
                }
                LOG.debug("Resource {} is {} {}", path, resource, ResourceUtil.isSyntheticResource(resource));
                return resource;
            }




            @Override
            public Iterable<Resource> getChildren(Resource resource) {
                return null;
            }

            @Override
            public void delete(Resource resource) throws PersistenceException {

            }

            @Override
            public Resource create(Resource resource, String s, Map<String, Object> map) throws PersistenceException {
                Resource childResource = resource.getChild(s);
                if ( childResource != null) {
                    throw new IllegalArgumentException("Child "+s+" already exists ");
                }
                Resource newResource = new MockRealResource(this, resource.getPath()+"/"+s, (String)map.get("sling:resourceType"), map);
                repository.put(newResource.getPath(), newResource);
                return newResource;
            }

            @Override
            public void revert() {

            }

            @Override
            public void commit() throws PersistenceException {
                LOG.debug("Committing");
                for(Map.Entry<String, Resource> e : repository.entrySet()) {
                    LOG.debug("Committing {} ", e.getKey());
                    Resource r = e.getValue();
                    ModifiableValueMap vm = r.adaptTo(ModifiableValueMap.class);
                    for (Map.Entry<String, Object> me : vm.entrySet()) {
                        if (me.getValue() instanceof InputStream) {
                            try {
                                String value = IOUtils.toString((InputStream) me.getValue());
                                LOG.debug("Converted {} {}  ", me.getKey(), value);
                                vm.put(me.getKey(), value);

                            } catch (IOException e1) {
                                throw new PersistenceException("Failed to commit input stream", e1);
                            }
                        }
                    }
                    LOG.debug("Converted {} ", vm);
                }
                LOG.debug("Committted {} ", repository);


            }

            @Override
            public boolean hasChanges() {
                return false;
            }
        };

        SlingHttpServletRequest request = new MockSlingHttpServlet3Request(null, null, null, null, null) {
            @Override
            public Object getAttribute(String name) {
                if ( "request-parts-iterator".equals(name)) {
                    return partsIterator;
                }
                return super.getAttribute(name);
            }

            @Override
            public ResourceResolver getResourceResolver() {
                return resourceResolver;
            }
        };
        streamedUplodOperation.doRun(request, response, changes);


        {
            Resource r = repository.get("/test/upload/location/test1.txt");
            Assert.assertNotNull(r);
            ValueMap m = r.adaptTo(ValueMap.class);
            Assert.assertNotNull(m);


            Assert.assertEquals("nt:file", m.get("jcr:primaryType"));

        }
        {
            Resource r = repository.get("/test/upload/location/test1.txt/jcr:content");
            Assert.assertNotNull(r);
            ValueMap m = r.adaptTo(ValueMap.class);
            Assert.assertNotNull(m);

            Assert.assertEquals("nt:resource", m.get("jcr:primaryType"));
            Assert.assertTrue(m.get("jcr:lastModified") instanceof Calendar);
            Assert.assertEquals("text/plain", m.get("jcr:mimeType"));
            Assert.assertEquals("test", m.get("jcr:data"));

        }
        {
            Resource r = repository.get("/test/upload/location/test2.txt");
            Assert.assertNotNull(r);
            ValueMap m = r.adaptTo(ValueMap.class);
            Assert.assertNotNull(m);


            Assert.assertEquals("nt:file", m.get("jcr:primaryType"));

        }
        {
            Resource r = repository.get("/test/upload/location/test2.txt/jcr:content");
            Assert.assertNotNull(r);
            ValueMap m = r.adaptTo(ValueMap.class);
            Assert.assertNotNull(m);


            Assert.assertEquals("nt:resource", m.get("jcr:primaryType"));
            Assert.assertTrue(m.get("jcr:lastModified") instanceof Calendar);
            Assert.assertEquals("text/plain2", m.get("jcr:mimeType"));
            Assert.assertEquals("test1234", m.get("jcr:data"));
        }


    }

    @Test
    public void testParts() throws PersistenceException, RepositoryException, UnsupportedEncodingException {
        List<Modification> changes = new ArrayList<>();
        PostResponse response = new AbstractPostResponse() {
            @Override
            protected void doSend(HttpServletResponse response) throws IOException {

            }

            @Override
            public void onChange(String type, String... arguments) {

            }

            @Override
            public String getPath() {
                return "/test/upload/location";
            }
        };

        List<Part> partsList = new ArrayList<>();
        partsList.add(new MockPart("test1.txt@Length", null, null, 0, new ByteArrayInputStream("8".getBytes("UTF-8")), Collections.EMPTY_MAP));
        partsList.add(new MockPart("test1.txt@Offset", null, null, 0, new ByteArrayInputStream("0".getBytes("UTF-8")), Collections.EMPTY_MAP));
        partsList.add(new MockPart(
                "test1.txt",
                "text/plain",
                "test1bad.txt",
                4,
                new ByteArrayInputStream("test".getBytes("UTF-8")),
                mapOf("Content-Length", "4")));
        partsList.add(new MockPart("test1.txt@Offset", null, null, 0, new ByteArrayInputStream("4".getBytes("UTF-8")), Collections.EMPTY_MAP));
        partsList.add(new MockPart(
                "test1.txt",
                "text/plain",
                "test1bad.txt",
                4,
                new ByteArrayInputStream("part".getBytes("UTF-8")),
                mapOf("Content-Length", "4")));
        partsList.add(new MockPart("*", "text/plain2", "test2.txt", 8, new ByteArrayInputStream("test1234".getBytes("UTF-8")), Collections.EMPTY_MAP));
        partsList.add(new MockPart("badformfield2", null, null, 0, new ByteArrayInputStream("testbadformfield2".getBytes("UTF-8")), Collections.EMPTY_MAP));
        final Iterator<Part> partsIterator = partsList.iterator();
        final Map<String, Resource> repository = new HashMap<>();
        final ResourceResolver resourceResolver = new MockResourceResolver() {
            @Override
            public Resource getResource(String path) {

                Resource resource = repository.get(path);

                if ( resource == null ) {
                    if ( "/test/upload/location".equals(path)) {
                        resource =  new MockRealResource(this, path, "sling:Folder");
                        repository.put(path,resource);
                        LOG.debug("Created {} ", path);

                    }
                }
                LOG.debug("Resource {} is {} {}", path, resource, ResourceUtil.isSyntheticResource(resource));
                return resource;
            }




            @Override
            public Iterable<Resource> getChildren(Resource resource) {

                List<Resource> children = new ArrayList<>();
                for(Map.Entry<String, Resource> e : repository.entrySet()) {
                    if (isChild(resource.getPath(), e.getKey())) {
                        children.add(e.getValue());
                    }
                }
                return children;
            }

            private boolean isChild(String path, String key) {
                if ( key.length() > path.length() && key.startsWith(path)) {
                    return !key.substring(path.length()+1).contains("/");
                }
                return false;
            }

            @Override
            public Iterator<Resource> listChildren(Resource parent) {
                return getChildren(parent).iterator();
            }

            @Override
            public void delete(Resource resource) throws PersistenceException {

            }

            @Override
            public Resource create(Resource resource, String s, Map<String, Object> map) throws PersistenceException {
                Resource childResource = resource.getChild(s);
                if ( childResource != null) {
                    throw new IllegalArgumentException("Child "+s+" already exists ");
                }
                String resourceType = (String)map.get("sling:resourceType");
                if ( resourceType == null) {
                    resourceType = (String)map.get("jcr:primaryType");
                }
                if ( resourceType == null) {
                    LOG.warn("Resource type null for {} {} ", resource,  resource.getPath()+"/"+s);
                }
                Resource newResource = new MockRealResource(this, resource.getPath()+"/"+s, resourceType, map);
                repository.put(newResource.getPath(), newResource);
                LOG.debug("Created Resource {} ", newResource.getPath());
                return newResource;
            }

            @Override
            public void revert() {

            }

            @Override
            public void commit() throws PersistenceException {
                LOG.debug("Committing");
                for(Map.Entry<String, Resource> e : repository.entrySet()) {
                    LOG.debug("Committing {} ", e.getKey());
                    Resource r = e.getValue();
                    ModifiableValueMap vm = r.adaptTo(ModifiableValueMap.class);
                    for (Map.Entry<String, Object> me : vm.entrySet()) {
                        if (me.getValue() instanceof InputStream) {
                            try {
                                String value = IOUtils.toString((InputStream) me.getValue());
                                LOG.debug("Converted {} {}  ", me.getKey(), value);
                                vm.put(me.getKey(), value);

                            } catch (IOException e1) {
                                throw new PersistenceException("Failed to commit input stream", e1);
                            }
                        }
                    }
                    LOG.debug("Converted {} ", vm);
                }
                LOG.debug("Comittted {} ", repository);


            }

            @Override
            public boolean hasChanges() {
                return false;
            }
        };

        SlingHttpServletRequest request = new MockSlingHttpServlet3Request(null, null, null, null, null) {
            @Override
            public Object getAttribute(String name) {
                if ( "request-parts-iterator".equals(name)) {
                    return partsIterator;
                }
                return super.getAttribute(name);
            }

            @Override
            public ResourceResolver getResourceResolver() {
                return resourceResolver;
            }
        };
        streamedUplodOperation.doRun(request, response, changes);


        {
            Resource r = repository.get("/test/upload/location/test1.txt");
            Assert.assertNotNull(r);
            ValueMap m = r.adaptTo(ValueMap.class);
            Assert.assertNotNull(m);


            Assert.assertEquals("nt:file", m.get("jcr:primaryType"));

        }
        {
            Resource r = repository.get("/test/upload/location/test1.txt/jcr:content");
            Assert.assertNotNull(r);
            ValueMap m = r.adaptTo(ValueMap.class);
            Assert.assertNotNull(m);

            Assert.assertEquals("nt:resource", m.get("jcr:primaryType"));
            Assert.assertTrue(m.get("jcr:lastModified") instanceof Calendar);
            Assert.assertEquals("text/plain", m.get("jcr:mimeType"));
            Assert.assertEquals("testpart", m.get("jcr:data"));

        }
        {
            Resource r = repository.get("/test/upload/location/test2.txt");
            Assert.assertNotNull(r);
            ValueMap m = r.adaptTo(ValueMap.class);
            Assert.assertNotNull(m);


            Assert.assertEquals("nt:file", m.get("jcr:primaryType"));

        }
        {
            Resource r = repository.get("/test/upload/location/test2.txt/jcr:content");
            Assert.assertNotNull(r);
            ValueMap m = r.adaptTo(ValueMap.class);
            Assert.assertNotNull(m);


            Assert.assertEquals("nt:resource", m.get("jcr:primaryType"));
            Assert.assertTrue(m.get("jcr:lastModified") instanceof Calendar);
            Assert.assertEquals("text/plain2", m.get("jcr:mimeType"));
            Assert.assertEquals("test1234", m.get("jcr:data"));
        }


    }

    @Test
    public void testPartsContentRange() throws PersistenceException, RepositoryException, UnsupportedEncodingException {
        List<Modification> changes = new ArrayList<>();
        PostResponse response = new AbstractPostResponse() {
            @Override
            protected void doSend(HttpServletResponse response) throws IOException {

            }

            @Override
            public void onChange(String type, String... arguments) {

            }

            @Override
            public String getPath() {
                return "/test/upload/location";
            }
        };

        List<Part> partsList = new ArrayList<>();
        partsList.add(new MockPart("formfield1", null, null, 0, new ByteArrayInputStream("testformfield1".getBytes("UTF-8")), Collections.EMPTY_MAP));
        partsList.add(new MockPart("formfield2", null, null, 0, new ByteArrayInputStream("testformfield2".getBytes("UTF-8")), Collections.EMPTY_MAP));
        partsList.add(new MockPart(
                "test1.txt",
                "text/plain",
                "test1bad.txt",
                4,
                new ByteArrayInputStream("test".getBytes("UTF-8")),
                mapOf("Content-Range","bytes 0-3/8", "Content-Length", "4")));
        partsList.add(new MockPart(
                "test1.txt",
                "text/plain",
                "test1bad.txt",
                4,
                new ByteArrayInputStream("part".getBytes("UTF-8")),
                mapOf("Content-Range","bytes 4-7/8", "Content-Length", "4")));
        partsList.add(new MockPart("*", "text/plain2", "test2.txt", 8, new ByteArrayInputStream("test1234".getBytes("UTF-8")), Collections.EMPTY_MAP));
        partsList.add(new MockPart("badformfield2", null, null, 0, new ByteArrayInputStream("testbadformfield2".getBytes("UTF-8")), Collections.EMPTY_MAP));
        final Iterator<Part> partsIterator = partsList.iterator();
        final Map<String, Resource> repository = new HashMap<>();
        final ResourceResolver resourceResolver = new MockResourceResolver() {
            @Override
            public Resource getResource(String path) {

                Resource resource = repository.get(path);

                if ( resource == null ) {
                    if ( "/test/upload/location".equals(path)) {
                        resource =  new MockRealResource(this, path, "sling:Folder");
                        repository.put(path,resource);
                        LOG.debug("Created {} ", path);

                    }
                }
                LOG.debug("Resource {} is {} {}", path, resource, ResourceUtil.isSyntheticResource(resource));
                return resource;
            }




            @Override
            public Iterable<Resource> getChildren(Resource resource) {

                List<Resource> children = new ArrayList<>();
                for(Map.Entry<String, Resource> e : repository.entrySet()) {
                    if (isChild(resource.getPath(), e.getKey())) {
                        children.add(e.getValue());
                    }
                }
                return children;
            }

            private boolean isChild(String path, String key) {
                if ( key.length() > path.length() && key.startsWith(path)) {
                    return !key.substring(path.length()+1).contains("/");
                }
                return false;
            }

            @Override
            public Iterator<Resource> listChildren(Resource parent) {
                return getChildren(parent).iterator();
            }

            @Override
            public void delete(Resource resource) throws PersistenceException {

            }

            @Override
            public Resource create(Resource resource, String s, Map<String, Object> map) throws PersistenceException {
                Resource childResource = resource.getChild(s);
                if ( childResource != null) {
                    throw new IllegalArgumentException("Child "+s+" already exists ");
                }
                String resourceType = (String)map.get("sling:resourceType");
                if ( resourceType == null) {
                    resourceType = (String)map.get("jcr:primaryType");
                }
                if ( resourceType == null) {
                    LOG.warn("Resource type null for {} {} ", resource,  resource.getPath()+"/"+s);
                }
                Resource newResource = new MockRealResource(this, resource.getPath()+"/"+s, resourceType, map);
                repository.put(newResource.getPath(), newResource);
                LOG.debug("Created Resource {} ", newResource.getPath());
                return newResource;
            }

            @Override
            public void revert() {

            }

            @Override
            public void commit() throws PersistenceException {
                LOG.debug("Committing");
                for(Map.Entry<String, Resource> e : repository.entrySet()) {
                    LOG.debug("Committing {} ", e.getKey());
                    Resource r = e.getValue();
                    ModifiableValueMap vm = r.adaptTo(ModifiableValueMap.class);
                    for (Map.Entry<String, Object> me : vm.entrySet()) {
                        if (me.getValue() instanceof InputStream) {
                            try {
                                String value = IOUtils.toString((InputStream) me.getValue());
                                LOG.debug("Converted {} {}  ", me.getKey(), value);
                                vm.put(me.getKey(), value);

                            } catch (IOException e1) {
                                throw new PersistenceException("Failed to commit input stream", e1);
                            }
                        }
                    }
                    LOG.debug("Converted {} ", vm);
                }
                LOG.debug("Comittted {} ", repository);


            }

            @Override
            public boolean hasChanges() {
                return false;
            }
        };

        SlingHttpServletRequest request = new MockSlingHttpServlet3Request(null, null, null, null, null) {
            @Override
            public Object getAttribute(String name) {
                if ( "request-parts-iterator".equals(name)) {
                    return partsIterator;
                }
                return super.getAttribute(name);
            }

            @Override
            public ResourceResolver getResourceResolver() {
                return resourceResolver;
            }
        };
        streamedUplodOperation.doRun(request, response, changes);


        {
            Resource r = repository.get("/test/upload/location/test1.txt");
            Assert.assertNotNull(r);
            ValueMap m = r.adaptTo(ValueMap.class);
            Assert.assertNotNull(m);


            Assert.assertEquals("nt:file", m.get("jcr:primaryType"));

        }
        {
            Resource r = repository.get("/test/upload/location/test1.txt/jcr:content");
            Assert.assertNotNull(r);
            ValueMap m = r.adaptTo(ValueMap.class);
            Assert.assertNotNull(m);

            Assert.assertEquals("nt:resource", m.get("jcr:primaryType"));
            Assert.assertTrue(m.get("jcr:lastModified") instanceof Calendar);
            Assert.assertEquals("text/plain", m.get("jcr:mimeType"));
            Assert.assertEquals("testpart", m.get("jcr:data"));

        }
        {
            Resource r = repository.get("/test/upload/location/test2.txt");
            Assert.assertNotNull(r);
            ValueMap m = r.adaptTo(ValueMap.class);
            Assert.assertNotNull(m);


            Assert.assertEquals("nt:file", m.get("jcr:primaryType"));

        }
        {
            Resource r = repository.get("/test/upload/location/test2.txt/jcr:content");
            Assert.assertNotNull(r);
            ValueMap m = r.adaptTo(ValueMap.class);
            Assert.assertNotNull(m);


            Assert.assertEquals("nt:resource", m.get("jcr:primaryType"));
            Assert.assertTrue(m.get("jcr:lastModified") instanceof Calendar);
            Assert.assertEquals("text/plain2", m.get("jcr:mimeType"));
            Assert.assertEquals("test1234", m.get("jcr:data"));
        }


    }



    private Map<String,Object> mapOf(String ... s) {
        Map<String, Object> m = new HashMap<>();
        for (int i = 0; i < s.length; i+=2) {
            m.put(s[i],s[i+1]);
        }
        return m;
    }
}
