import sys
import subprocess
import tempfile
import os

# Python programs (d group)
python_programs = {
    "d1": """# Write a program to sort a list of N elements using selection sort technique.
def selection_sort(arr):
    for i in range(len(arr)):
        min_idx = i
        for j in range(i+1, len(arr)):
            if arr[j] < arr[min_idx]:
                min_idx = j
        arr[i], arr[min_idx] = arr[min_idx], arr[i]
    return arr

print(selection_sort([64, 25, 12, 22, 11]))
""",

    "d2": """# Program to find maximum and minimum value in an array using divide and conquer.
def find_min_max(arr, low, high):
    if low == high:
        return arr[low], arr[low]
    elif high == low + 1:
        return (min(arr[low], arr[high]), max(arr[low], arr[high]))
    else:
        mid = (low + high) // 2
        min1, max1 = find_min_max(arr, low, mid)
        min2, max2 = find_min_max(arr, mid+1, high)
        return min(min1, min2), max(max1, max2)

arr = [3, 5, 1, 8, 9, 2]
print(find_min_max(arr, 0, len(arr)-1))
""",

    "d3": """# Write a program to implement merge sort algorithm for sorting a list of integers in ascending order.
def merge_sort(arr):
    if len(arr) > 1:
        mid = len(arr)//2
        L = arr[:mid]
        R = arr[mid:]

        merge_sort(L)
        merge_sort(R)

        i = j = k = 0
        while i < len(L) and j < len(R):
            if L[i] < R[j]:
                arr[k] = L[i]
                i += 1
            else:
                arr[k] = R[j]
                j += 1
            k += 1

        while i < len(L):
            arr[k] = L[i]
            i += 1
            k += 1

        while j < len(R):
            arr[k] = R[j]
            j += 1
            k += 1

arr = [38, 27, 43, 3, 9, 82, 10]
merge_sort(arr)
print(arr)
""",

    "d4": """# Write a program to implement the BFS (Breadth First Search) algorithm for a graph.
from collections import deque

def bfs(graph, start):
    visited = set()
    queue = deque([start])
    while queue:
        vertex = queue.popleft()
        if vertex not in visited:
            print(vertex, end=' ')
            visited.add(vertex)
            queue.extend(graph[vertex] - visited)

graph = {1:{2,3}, 2:{4,5}, 3:{6}, 4:set(), 5:set(), 6:set()}
bfs(graph, 1)
""",

    "d5": """# Write a program to implement the DFS (Depth First Search) algorithm for a graph.
def dfs(graph, start, visited=None):
    if visited is None:
        visited = set()
    if start not in visited:
        print(start, end=' ')
        visited.add(start)
        for next in graph[start] - visited:
            dfs(graph, next, visited)

graph = {1:{2,3}, 2:{4,5}, 3:{6}, 4:set(), 5:set(), 6:set()}
dfs(graph, 1)
"""
}

# R programs (r group) – real code
r_programs = {
    "r1": """
x = c(4, 5, 6)
y = c(1, 2, 3, 4)
if (length(x) == length(y)) {
  print("both vector length same")
} else {
  print("both vector are not same")
}
""",
    "r2": """
for (i in 1:10) {
  print(paste("i =", i))
  if (i == 5) stop("iteration stopped (on condition) at 5")
}
""",
    "r3": """
fact <- function(n) {
  if (n <= 1) return(1)
  else return(n * factorial(n - 1))
}
n <- as.numeric(readline("Enter n value: "))
print(paste("Factorial of number is:", fact(n)))
""",
    "r4": """
a <- c(8, 10, 4, 6, 23, 5, 9, 8, 5, 4, 8, 7, 8)
print(paste("mean of vector =", mean(a)))
print(paste("median of vector =", median(a)))
print(paste("mode of vector =", names(sort(-table(a)))[1]))
""",
    "r5": """
output_file_path <- "D:/out.txt"
data <- "hello, my name is A"
writeLines(data, output_file_path)
print(paste("Reading a file =", readLines("D:/out.txt")))
""",
    "r6": """
df = data.frame(
  name = c("amiya", "roy", "aish"),
  programming_language = c("C", "Python", "Java"),
  age = c(22, 21, 23)
)
cat("data in dataframe is:\\n")
print(df)
newdf = rbind(
  df,
  data.frame(name = c("Pavan"), programming_language = c("R"), age = c(24))
)
cat("after adding new row(s):\\n")
print(newdf)
""",
    "r7": """
groupA<-c(18,21,24,27,30)
groupB<-c(17,20,23,26,29)
res_ttest<-t.test(groupA,groupB)
print(res_ttest)
"""
}

def open_in_idle(code: str):
    """Open Python code in IDLE."""
    with tempfile.NamedTemporaryFile("w", suffix=".py", delete=False) as f:
        f.write(code)
        temp_path = f.name
    subprocess.Popen([sys.executable, "-m", "idlelib", temp_path])

def open_in_rstudio(code: str):
    """Open R code in RStudio (if installed)."""
    with tempfile.NamedTemporaryFile("w", suffix=".R", delete=False) as f:
        f.write(code)
        temp_path = f.name
    possible_paths = ["rstudio", "C:\\Program Files\\RStudio\\bin\\rstudio.exe"]
    for path in possible_paths:
        try:
            subprocess.Popen([path, temp_path])
            return
        except FileNotFoundError:
            continue
    print("Error: RStudio not found. Please install it and ensure it's in PATH.")

def main():
    if len(sys.argv) < 2 or sys.argv[1] == "-h":
        print("# Commands:\n  ig d -h\n  ig r -h")
        return

    cmd = sys.argv[1]

    if cmd == "d" and len(sys.argv) > 2 and sys.argv[2] == "-h":
        print("# Available Python programs:")
        print("  - d1: 1] Selection Sort")
        print("  - d2: 2] Find min/max using Divide & Conquer")
        print("  - d3: 3] Merge Sort")
        print("  - d4: 4] BFS Algorithm")
        print("  - d5: 5] DFS Algorithm")
        return

    if cmd == "r" and len(sys.argv) > 2 and sys.argv[2] == "-h":
        print("# Available R programs:")
        print("  - r1: 1] else stmt & it operator on vectors")
        print("  - r2: 2] for loop & stop with error message")
        print("  - r3: 3] Factorial using recursion")
        print("  - r4: 4] Mean, Median & Mode")
        print("  - r5: 5] Read & Write file")
        print("  - r6: 6] DataFrame manipulation")
        print("  - r7: 7] ANOVA test")
        return

    if cmd in python_programs:
        open_in_idle(python_programs[cmd])
    elif cmd in r_programs:
        open_in_rstudio(r_programs[cmd])
    else:
        print("Unknown command. Use ig -h for help.")

if __name__ == "__main__":
    main()
