
/* ====================================================================
   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.poi.hslf.record;

import static org.apache.poi.hslf.usermodel.HSLFSlideShow.PP95_DOCUMENT;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException;
import org.apache.poi.hslf.exceptions.OldPowerPointFormatException;
import org.apache.poi.poifs.filesystem.DirectoryNode;
import org.apache.poi.poifs.filesystem.DocumentEntry;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.StringUtil;

/**
 * This is a special kind of Atom, because it doesn't live inside the
 *  PowerPoint document. Instead, it lives in a separate stream in the
 *  document. As such, it has to be treated specially
 */
public class CurrentUserAtom
{
	private final static POILogger logger = POILogFactory.getLogger(CurrentUserAtom.class);
	//arbitrarily selected; may need to increase
	private static final int MAX_RECORD_LENGTH = 1_000_000;

	/** Standard Atom header */
	private static final byte[] atomHeader = new byte[] { 0, 0, -10, 15 };
	/** The PowerPoint magic number for a non-encrypted file */
	private static final byte[] headerToken = new byte[] { 95, -64, -111, -29 };
	/** The PowerPoint magic number for an encrypted file */
	private static final byte[] encHeaderToken = new byte[] { -33, -60, -47, -13 };
	// The Powerpoint 97 version, major and minor numbers
	// byte[] ppt97FileVer = new byte[] { 8, 00, -13, 03, 03, 00 };

	/** The version, major and minor numbers */
	private int docFinalVersion;
	private byte docMajorNo;
	private byte docMinorNo;

	/** The Offset into the file for the current edit */
    private long currentEditOffset;
	/** The Username of the last person to edit the file */
	private String lastEditUser;
	/** The document release version. Almost always 8 */
	private long releaseVersion;

	/** Only correct after reading in or writing out */
	private byte[] _contents;
	
	/** Flag for encryption state of the whole file */
	private boolean isEncrypted;


	/* ********************* getter/setter follows *********************** */

	public int  getDocFinalVersion() { return docFinalVersion; }
	public byte getDocMajorNo()       { return docMajorNo; }
	public byte getDocMinorNo()       { return docMinorNo; }

	public long getReleaseVersion()  { return releaseVersion; }
	public void setReleaseVersion(long rv) { releaseVersion = rv; }

	/** Points to the UserEditAtom */
	public long getCurrentEditOffset() { return currentEditOffset; }
	public void setCurrentEditOffset(long id ) { currentEditOffset = id; }

	public String getLastEditUsername() { return lastEditUser; }
	public void setLastEditUsername(String u) { lastEditUser = u; }

	public boolean isEncrypted() { return isEncrypted; }
	public void setEncrypted(boolean isEncrypted) { this.isEncrypted = isEncrypted; }
	

	/* ********************* real code follows *************************** */

	/**
	 * Create a new Current User Atom
	 */
	public CurrentUserAtom() {
		_contents = new byte[0];

		// Initialise to empty
		docFinalVersion = 0x03f4;
		docMajorNo = 3;
		docMinorNo = 0;
		releaseVersion = 8;
		currentEditOffset = 0;
		lastEditUser = "Apache POI";
		isEncrypted = false;
	}


	/** 
	 * Find the Current User in the filesystem, and create from that
	 */
	public CurrentUserAtom(DirectoryNode dir) throws IOException {
		// Decide how big it is
		DocumentEntry docProps =
			(DocumentEntry)dir.getEntry("Current User");
		
		// If it's clearly junk, bail out
		if(docProps.getSize() > 131072) {
			throw new CorruptPowerPointFileException("The Current User stream is implausably long. It's normally 28-200 bytes long, but was " + docProps.getSize() + " bytes");
		}
		
		// Grab the contents
		int len = docProps.getSize();
		_contents = IOUtils.safelyAllocate(len, MAX_RECORD_LENGTH);
		InputStream in = dir.createDocumentInputStream("Current User");
		int readLen = in.read(_contents);
		in.close();

        if (len != readLen) {
            throw new IOException("Current User input stream ended prematurely - expected "+len+" bytes - received "+readLen+" bytes");
        }
		
		
		// See how long it is. If it's under 28 bytes long, we can't
		//  read it
		if(_contents.length < 28) {
		    boolean isPP95 = dir.hasEntry(PP95_DOCUMENT);
		    // PPT95 has 4 byte size, then data
			if (!isPP95 && _contents.length >= 4) {
				int size = LittleEndian.getInt(_contents);
				isPP95 = (size + 4 == _contents.length);
			}

			if (isPP95) {
			    throw new OldPowerPointFormatException("Based on the Current User stream, you seem to have supplied a PowerPoint95 file, which isn't supported");
			} else {
			    throw new CorruptPowerPointFileException("The Current User stream must be at least 28 bytes long, but was only " + _contents.length);
			}
		}

		// Set everything up
		init();
	}

	/**
	 * Actually do the creation from a block of bytes
	 */
	private void init() {
		// First up is the size, in 4 bytes, which is fixed
		// Then is the header
		
	    isEncrypted = (LittleEndian.getInt(encHeaderToken) == LittleEndian.getInt(_contents,12)); 
	    
		// Grab the edit offset
		currentEditOffset = LittleEndian.getUInt(_contents,16);

		// Grab the versions
		docFinalVersion = LittleEndian.getUShort(_contents,22);
		docMajorNo = _contents[24];
		docMinorNo = _contents[25];

		// Get the username length
		long usernameLen = LittleEndian.getUShort(_contents,20);
		if(usernameLen > 512) {
			// Handle the case of it being garbage
			logger.log(POILogger.WARN, "Warning - invalid username length " + usernameLen + " found, treating as if there was no username set");
			usernameLen = 0;
		}

		// Now we know the length of the username, 
		//  use this to grab the revision
		if(_contents.length >= 28+(int)usernameLen + 4) {
			releaseVersion = LittleEndian.getUInt(_contents,28+(int)usernameLen);
		} else {
			// No revision given, as not enough data. Odd
			releaseVersion = 0;
		}

		// Grab the unicode username, if stored
		int start = 28+(int)usernameLen+4;
		int len = 2*(int)usernameLen;

		if(_contents.length >= start+len) {
			byte[] textBytes = IOUtils.safelyAllocate(len, MAX_RECORD_LENGTH);
			System.arraycopy(_contents,start,textBytes,0,len);
			lastEditUser = StringUtil.getFromUnicodeLE(textBytes);
		} else {
			// Fake from the 8 bit version
			byte[] textBytes = IOUtils.safelyAllocate(usernameLen, MAX_RECORD_LENGTH);
			System.arraycopy(_contents,28,textBytes,0,(int)usernameLen);
			lastEditUser = StringUtil.getFromCompressedUnicode(textBytes,0,(int)usernameLen);
		}
	}


	/**
	 * Writes ourselves back out
	 */
	public void writeOut(OutputStream out) throws IOException {
		// Decide on the size
		//  8 = atom header
		//  20 = up to name
		//  4 = revision
		//  3 * len = ascii + unicode
		int size = 8 + 20 + 4 + (3 * lastEditUser.length());
		_contents = IOUtils.safelyAllocate(size, MAX_RECORD_LENGTH);

		// First we have a 8 byte atom header
		System.arraycopy(atomHeader,0,_contents,0,4);	
		// Size is 20+user len + revision len(4)
		int atomSize = 20+4+lastEditUser.length();
		LittleEndian.putInt(_contents,4,atomSize);

		// Now we have the size of the details, which is 20
		LittleEndian.putInt(_contents,8,20);

		// Now the ppt un-encrypted header token (4 bytes)
		System.arraycopy((isEncrypted ? encHeaderToken : headerToken),0,_contents,12,4);

		// Now the current edit offset
		LittleEndian.putInt(_contents,16,(int)currentEditOffset);

		// The username gets stored twice, once as US 
		//  ascii, and again as unicode laster on
		byte[] asciiUN = IOUtils.safelyAllocate(lastEditUser.length(), MAX_RECORD_LENGTH);
		StringUtil.putCompressedUnicode(lastEditUser,asciiUN,0);
		
		// Now we're able to do the length of the last edited user
		LittleEndian.putShort(_contents,20,(short)asciiUN.length);
		
		// Now the file versions, 2+1+1
		LittleEndian.putShort(_contents,22,(short)docFinalVersion);
		_contents[24] = docMajorNo;
		_contents[25] = docMinorNo;

		// 2 bytes blank
		_contents[26] = 0;
		_contents[27] = 0;

		// At this point we have the username as us ascii
		System.arraycopy(asciiUN,0,_contents,28,asciiUN.length);

		// 4 byte release version
		LittleEndian.putInt(_contents,28+asciiUN.length,(int)releaseVersion);

		// username in unicode
		byte [] ucUN = IOUtils.safelyAllocate(lastEditUser.length()*2, MAX_RECORD_LENGTH);
		StringUtil.putUnicodeLE(lastEditUser,ucUN,0);
		System.arraycopy(ucUN,0,_contents,28+asciiUN.length+4,ucUN.length);

		// Write out
		out.write(_contents);
	}

	/**
	 * Writes ourselves back out to a filesystem
	 */
	public void writeToFS(POIFSFileSystem fs) throws IOException {
		// Grab contents
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		writeOut(baos);
		ByteArrayInputStream bais = 
			new ByteArrayInputStream(baos.toByteArray());

		// Write out
		fs.createOrUpdateDocument(bais,"Current User");
	}
}
