Move chunk/master data structures into libs
diff --git a/master/core b/master/core
deleted file mode 100644
index e69de29..0000000
--- a/master/core
+++ /dev/null
diff --git a/master/master.go b/master/master.go
deleted file mode 100644
index 73ac143..0000000
--- a/master/master.go
+++ /dev/null
@@ -1,60 +0,0 @@
-package main
-
-import "context"
-import "flag"
-import "fmt"
-import "log"
-import "net"
-
-import "google.golang.org/grpc"
-
-import pc "pcloud"
-
-var port int
-
-func init() {
-	flag.IntVar(&port, "port", 123, "Port to listen on.")
-}
-
-type chunkServer struct {
-	address string
-}
-
-type metadataStorage struct {
-	chunkServer []string
-}
-
-func (s *metadataStorage) AddChunkServer(
-	ctx context.Context,
-	request *pc.AddChunkServerRequest) (*pc.AddChunkServerResponse, error) {
-	s.chunkServer = append(s.chunkServer, request.GetAddress())
-	log.Printf("Registered Chunk server: %s", request.GetAddress())
-	return &pc.AddChunkServerResponse{}, nil
-}
-
-func (s *metadataStorage) CreateBlob(
-	ctx context.Context,
-	request *pc.CreateBlobRequest) (*pc.CreateBlobResponse, error) {
-	return nil, nil
-}
-
-func (s *metadataStorage) GetBlobMetadata(
-	ctx context.Context,
-	request *pc.GetBlobMetadataRequest) (*pc.GetBlobMetadataResponse, error) {
-	return nil, nil
-}
-
-func main() {
-	flag.Parse()
-	log.Print("Master server starting")
-
-	lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
-	if err != nil {
-		log.Fatalf("Failed to listen on port %d: %v", port, err)
-	}
-	log.Printf("Listening on port: %d", port)
-	server := grpc.NewServer()
-	pc.RegisterMetadataStorageServer(server, &metadataStorage{})
-	log.Print("Master serving")
-	server.Serve(lis)
-}
diff --git a/master/server.go b/master/server.go
new file mode 100644
index 0000000..2eb2898
--- /dev/null
+++ b/master/server.go
@@ -0,0 +1,85 @@
+package master
+
+import "context"
+import "log"
+import "math/rand"
+
+import "github.com/google/uuid"
+
+import "pcloud/api"
+
+type chunkServers struct {
+	address string
+}
+
+type BlobStatus int
+
+const (
+	NEW BlobStatus = iota
+)
+
+type ChunkStatus int
+
+const (
+	ASSIGNED ChunkStatus = iota
+	STORED
+)
+
+type chunkReplica struct {
+	chunkServer string
+	status      ChunkStatus
+}
+
+type chunk struct {
+	id      string
+	replica []chunkReplica
+}
+
+type blob struct {
+	id     string
+	status BlobStatus
+	chunks []chunk
+}
+
+type MasterServer struct {
+	chunkServers []string
+	blobs        []*blob
+}
+
+func NewMasterServer() *MasterServer {
+	return &MasterServer{}
+}
+
+func (s *MasterServer) AddChunkServer(
+	ctx context.Context,
+	request *api.AddChunkServerRequest) (*api.AddChunkServerResponse, error) {
+	s.chunkServers = append(s.chunkServers, request.Address)
+	log.Printf("Registered Chunk server: %s", request.Address)
+	return &api.AddChunkServerResponse{}, nil
+}
+
+func (s *MasterServer) CreateBlob(
+	ctx context.Context,
+	request *api.CreateBlobRequest) (*api.CreateBlobResponse, error) {
+	if int(request.NumReplicas) > len(s.chunkServers) {
+		return nil, nil
+	}
+	resp := api.CreateBlobResponse{
+		BlobId: uuid.New().String(),
+		Chunk: []*api.ChunkStorageMetadata{
+			{ChunkId: uuid.New().String()},
+		}}
+	ids := rand.Perm(len(s.chunkServers))
+	for i := 0; i < int(request.NumReplicas); i++ {
+		resp.Chunk[0].Server = append(
+			resp.Chunk[0].Server,
+			s.chunkServers[ids[i]])
+	}
+	return &resp, nil
+}
+
+func (s *MasterServer) GetBlobMetadata(
+	ctx context.Context,
+	request *api.GetBlobMetadataRequest) (*api.GetBlobMetadataResponse, error) {
+	return nil, nil
+}