<commit_before>package service;

import static org.eclipse.egit.github.core.client.IGitHubConstants.SEGMENT_REPOS;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import model.Model;
import model.TurboLabel;
import model.TurboMilestone;
import model.TurboUser;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.eclipse.egit.github.core.Comment;
import org.eclipse.egit.github.core.IRepositoryIdProvider;
import org.eclipse.egit.github.core.Issue;
import org.eclipse.egit.github.core.IssueEvent;
import org.eclipse.egit.github.core.Label;
import org.eclipse.egit.github.core.Milestone;
import org.eclipse.egit.github.core.Repository;
import org.eclipse.egit.github.core.RepositoryContents;
import org.eclipse.egit.github.core.RepositoryId;
import org.eclipse.egit.github.core.User;
import org.eclipse.egit.github.core.client.GitHubRequest;
import org.eclipse.egit.github.core.client.PageIterator;
import org.eclipse.egit.github.core.client.RequestException;
import org.eclipse.egit.github.core.service.CollaboratorService;
import org.eclipse.egit.github.core.service.ContentsService;
import org.eclipse.egit.github.core.service.IssueService;
import org.eclipse.egit.github.core.service.MarkdownService;
import org.eclipse.egit.github.core.service.MilestoneService;
import org.markdown4j.Markdown4jProcessor;

import service.updateservice.CommentUpdateService;
import service.updateservice.ModelUpdater;
import storage.DataCacheFileHandler;
import storage.TurboRepoData;
import stubs.ServiceManagerStub;

/**
 * Singleton class that provides access to the GitHub API services required by HubTurbo
 * 
 * Only data from a single repository can be loaded at any point of time. 
 * The currently loaded repository is stored in the application's ServiceManager instance
 * 
 * Also holds a reference to the application's current Model instance, which stores the repository's 
 * labels, milestones, assignees and issues.
 * */
public class ServiceManager {
	private static final Logger logger = LogManager.getLogger(ServiceManager.class.getName());
	public static final boolean isTestMode = false;
	
	protected static final String METHOD_PUT = "PUT";
	protected static final String METHOD_POST = "POST";
	
	public static final String KEY_ISSUES = "issues";
	public static final String KEY_MILESTONES = "milestones";
	public static final String KEY_LABELS = "labels";
	public static final String KEY_COLLABORATORS = "collaborators";
	public static final String KEY_FEEDS = "feeds";
	public static final int MAX_FEED = 20;
	private static final ServiceManager serviceManagerInstance = new ServiceManager();
	private GitHubClientExtended githubClient;
	
	private CollaboratorService collabService;
	private IssueServiceExtended issueService;
	private LabelServiceFixed labelService;
	private MilestoneService milestoneService;
	private RepositoryServiceExtended repositoryService;
	private MarkdownService markdownService;
	private ContentsService contentService;
	
	private ModelUpdater modelUpdater;
	private Model model;
	private RepositoryId repoId;
	private String issuesETag = null;
	private String collabsETag = null;
	private String labelsETag = null;
	private String milestonesETag = null;
	private String issueCheckTime = null;
	
	public static final String STATE_ALL = "all";
	public static final String STATE_OPEN = "open";
	public static final String STATE_CLOSED = "closed";

	// Login state
	private String password;

	protected ServiceManager(){
		githubClient = new GitHubClientExtended();
		collabService = new CollaboratorService(githubClient);
		issueService = new IssueServiceExtended(githubClient);
		labelService = new LabelServiceFixed(githubClient);
		milestoneService = new MilestoneService(githubClient);
		repositoryService = new RepositoryServiceExtended(githubClient);
		markdownService = new MarkdownService(githubClient);
		contentService = new ContentsService(githubClient);
		model = new Model();
	}

	public IRepositoryIdProvider getRepoId(){
		return repoId;
	}
	
	public Model getModel(){
		return model;
	}
	
	public Date getLastModelUpdateTime(){
		if(modelUpdater != null){
			return modelUpdater.getLastUpdateTime();
		}
		return null;
	}
	
	public void setupAndStartModelUpdate() {
		if(modelUpdater != null){
			stopModelUpdate();
		}
		if(repoId != null){
			modelUpdater = new ModelUpdater(githubClient, model, issuesETag, collabsETag, labelsETag, milestonesETag, issueCheckTime);
			modelUpdater.startModelUpdate();
		}
	}
	
	public void restartModelUpdate(){
		if(modelUpdater != null){
			modelUpdater.stopModelUpdate();
			modelUpdater.startModelUpdate();
		}
	}
	
	public void stopModelUpdate(){
		if(modelUpdater !=  null){
			modelUpdater.stopModelUpdate();
		}
	}
	
	public static ServiceManager getInstance(){
		if(!isTestMode){
			return serviceManagerInstance;
		}else{
			return new ServiceManagerStub();
		}
	}
	
	public boolean login(String userId, String password){
		this.password = password;
		githubClient.setCredentials(userId, password);
		try {
			GitHubRequest request = new GitHubRequest();
			request.setUri("/");
			githubClient.get(request);
		} catch (IOException e) {
			// Login failed
			return false;
		}
		return true;
	}
	
	public String getUserId(){
		return githubClient.getUser();
	}
	
	public String getPassword(){
		assert password != null;
		return password;
	}

	public boolean setupRepository(String owner, String name) throws IOException{
		logger.info("Authenticating...");
		repoId = RepositoryId.create(owner, name);
		if(checkRepository(repoId)){
			return model.loadComponents(repoId);
		}else{
			throw new IOException("Cannot access repository"); //TODO: create specific exception for this
		}<commit_msg>Added logging to report reasons for unsuccessful login<commit_after>package service;

import static org.eclipse.egit.github.core.client.IGitHubConstants.SEGMENT_REPOS;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import model.Model;
import model.TurboLabel;
import model.TurboMilestone;
import model.TurboUser;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.eclipse.egit.github.core.Comment;
import org.eclipse.egit.github.core.IRepositoryIdProvider;
import org.eclipse.egit.github.core.Issue;
import org.eclipse.egit.github.core.IssueEvent;
import org.eclipse.egit.github.core.Label;
import org.eclipse.egit.github.core.Milestone;
import org.eclipse.egit.github.core.Repository;
import org.eclipse.egit.github.core.RepositoryContents;
import org.eclipse.egit.github.core.RepositoryId;
import org.eclipse.egit.github.core.User;
import org.eclipse.egit.github.core.client.GitHubRequest;
import org.eclipse.egit.github.core.client.PageIterator;
import org.eclipse.egit.github.core.client.RequestException;
import org.eclipse.egit.github.core.service.CollaboratorService;
import org.eclipse.egit.github.core.service.ContentsService;
import org.eclipse.egit.github.core.service.IssueService;
import org.eclipse.egit.github.core.service.MarkdownService;
import org.eclipse.egit.github.core.service.MilestoneService;
import org.markdown4j.Markdown4jProcessor;

import service.updateservice.CommentUpdateService;
import service.updateservice.ModelUpdater;
import storage.DataCacheFileHandler;
import storage.TurboRepoData;
import stubs.ServiceManagerStub;

/**
 * Singleton class that provides access to the GitHub API services required by HubTurbo
 * 
 * Only data from a single repository can be loaded at any point of time. 
 * The currently loaded repository is stored in the application's ServiceManager instance
 * 
 * Also holds a reference to the application's current Model instance, which stores the repository's 
 * labels, milestones, assignees and issues.
 * */
public class ServiceManager {
	private static final Logger logger = LogManager.getLogger(ServiceManager.class.getName());
	public static final boolean isTestMode = false;
	
	protected static final String METHOD_PUT = "PUT";
	protected static final String METHOD_POST = "POST";
	
	public static final String KEY_ISSUES = "issues";
	public static final String KEY_MILESTONES = "milestones";
	public static final String KEY_LABELS = "labels";
	public static final String KEY_COLLABORATORS = "collaborators";
	public static final String KEY_FEEDS = "feeds";
	public static final int MAX_FEED = 20;
	private static final ServiceManager serviceManagerInstance = new ServiceManager();
	private GitHubClientExtended githubClient;
	
	private CollaboratorService collabService;
	private IssueServiceExtended issueService;
	private LabelServiceFixed labelService;
	private MilestoneService milestoneService;
	private RepositoryServiceExtended repositoryService;
	private MarkdownService markdownService;
	private ContentsService contentService;
	
	private ModelUpdater modelUpdater;
	private Model model;
	private RepositoryId repoId;
	private String issuesETag = null;
	private String collabsETag = null;
	private String labelsETag = null;
	private String milestonesETag = null;
	private String issueCheckTime = null;
	
	public static final String STATE_ALL = "all";
	public static final String STATE_OPEN = "open";
	public static final String STATE_CLOSED = "closed";

	// Login state
	private String password;

	protected ServiceManager(){
		githubClient = new GitHubClientExtended();
		collabService = new CollaboratorService(githubClient);
		issueService = new IssueServiceExtended(githubClient);
		labelService = new LabelServiceFixed(githubClient);
		milestoneService = new MilestoneService(githubClient);
		repositoryService = new RepositoryServiceExtended(githubClient);
		markdownService = new MarkdownService(githubClient);
		contentService = new ContentsService(githubClient);
		model = new Model();
	}

	public IRepositoryIdProvider getRepoId(){
		return repoId;
	}
	
	public Model getModel(){
		return model;
	}
	
	public Date getLastModelUpdateTime(){
		if(modelUpdater != null){
			return modelUpdater.getLastUpdateTime();
		}
		return null;
	}
	
	public void setupAndStartModelUpdate() {
		if(modelUpdater != null){
			stopModelUpdate();
		}
		if(repoId != null){
			modelUpdater = new ModelUpdater(githubClient, model, issuesETag, collabsETag, labelsETag, milestonesETag, issueCheckTime);
			modelUpdater.startModelUpdate();
		}
	}
	
	public void restartModelUpdate(){
		if(modelUpdater != null){
			modelUpdater.stopModelUpdate();
			modelUpdater.startModelUpdate();
		}
	}
	
	public void stopModelUpdate(){
		if(modelUpdater !=  null){
			modelUpdater.stopModelUpdate();
		}
	}
	
	public static ServiceManager getInstance(){
		if(!isTestMode){
			return serviceManagerInstance;
		}else{
			return new ServiceManagerStub();
		}
	}
	
	public boolean login(String userId, String password){
		this.password = password;
		githubClient.setCredentials(userId, password);
		try {
			GitHubRequest request = new GitHubRequest();
			request.setUri("/");
			githubClient.get(request);
		} catch (IOException e) {
			logger.error(e.getLocalizedMessage(), e);
			// Login failed
			return false;
		}
		return true;
	}
	
	public String getUserId(){
		return githubClient.getUser();
	}
	
	public String getPassword(){
		assert password != null;
		return password;
	}

	public boolean setupRepository(String owner, String name) throws IOException{
		logger.info("Authenticating...");
		repoId = RepositoryId.create(owner, name);
		if(checkRepository(repoId)){
			return model.loadComponents(repoId);
		}else{
			throw new IOException("Cannot access repository"); //TODO: create specific exception for this
		}
{'fraction_non_alphanumeric': 0.08926218708827405, 'fraction_numerical': 0.0009881422924901185, 'mean_word_length': 5.449814126394052, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7035741', 'n_tokens_mistral': 3686, 'n_tokens_neox': 3437, 'n_words': 905}