package com.example.javancss;

import java.io.File;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;
import java.util.concurrent.locks.Lock;

import com.pmease.quickbuild.aggregationsupport.Aggregation;
import com.pmease.quickbuild.annotation.Editable;
import com.pmease.quickbuild.model.Build;
import com.pmease.quickbuild.model.Configuration;
import com.pmease.quickbuild.util.BeanUtils;
import com.pmease.quickbuild.util.LockUtils;
import com.pmease.quickbuild.util.datastore.FileDb;

@Editable(name="Java NCSS Aggregation")
public class JavaNCSSAggregation extends Aggregation {

	private static final long serialVersionUID = 1L;

	@Override
	public void aggregate(final Configuration configuration, final Build build) {
		File metricsFile = new File(build.getPublishDir(), JavaNCSSPlugin.METRICS_FILE); 
		Lock lock = LockUtils.lockForRead(metricsFile);
		final Metrics metrics[] = new Metrics[]{null};
		try {
			if (metricsFile.exists())
				metrics[0] = (Metrics) BeanUtils.readFile(metricsFile);
		} finally {
			lock.unlock();
		}
		if (metrics[0] != null) {
			File aggregationDir = new File(configuration.getPublishDir(), JavaNCSSPlugin.AGGREGATION_DIR);
			lock = LockUtils.lockForWrite(aggregationDir);
			try {
				new FileDb(new File(aggregationDir, getName()), new AggregationDbMigrator()).write(new FileDb.Callback() {
					
					public Object execute(Connection conn) throws SQLException {
						Date endDate = build.getEndDate();
						int day = (int) (endDate.getTime() / (24*3600*1000));
						Statement stmt = conn.createStatement();
						ResultSet rs = stmt.executeQuery("select count, source_lines, comment_lines from metrics " +
								"where day=" + day + " and configuration=" + build.getConfiguration().getId());
						if (rs.next()) {
							int count = rs.getInt("count")+1;
							int sourceLines = rs.getInt("source_lines") + metrics[0].getSourceLines();
							int commentLines = rs.getInt("comment_lines") + metrics[0].getCommentLines();
							stmt.executeUpdate("update metrics set count=" + count + ", source_lines=" + 
									sourceLines + ", comment_lines=" + commentLines + " where day=" + 
									day + " and configuration=" + build.getConfiguration().getId());
						} else {
							stmt.executeUpdate("insert into metrics values(" + day + ", " + 
									build.getConfiguration().getId() + ", 1, " + 
									metrics[0].getSourceLines() + ", " + metrics[0].getCommentLines() + ")");
						}
						
						rs = stmt.executeQuery("select count from metrics where day=0 and configuration=" + 
								build.getConfiguration().getId());
						if (rs.next()) {
							stmt.executeUpdate("update metrics set source_lines=" + metrics[0].getSourceLines() + 
									", comment_lines=" + metrics[0].getCommentLines() + " where day=0 and " +
									"configuration=" + build.getConfiguration().getId());
						} else {
							stmt.executeUpdate("insert into metrics values(0, " + 
									build.getConfiguration().getId() + ", 1, " + metrics[0].getSourceLines() + 
									", " + metrics[0].getCommentLines() + ")");
						}
						return null;
					}
	
				});
			} finally {
				lock.unlock();
			}
		}
	}

}
